Skip to content

Commit

Permalink
Fixes and Additions for HID support
Browse files Browse the repository at this point in the history
The following things were fixed:
* KSharedMemory
* KSyncObject (and how waiting on them works)
* Inclusion of Headers
What was added:
* Transfer Memory
* svcSleepThread
  • Loading branch information
PixelyIon committed Oct 13, 2019
1 parent f7effe8 commit ec71735
Show file tree
Hide file tree
Showing 44 changed files with 680 additions and 351 deletions.
6 changes: 4 additions & 2 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ add_subdirectory("libraries/fmt")

set(source_DIR ${CMAKE_SOURCE_DIR}/src/main/cpp)

include_directories(${source_DIR})
include_directories(${source_DIR}/skyline)

add_library(skyline SHARED
${source_DIR}/main.cpp
Expand All @@ -25,13 +25,15 @@ add_library(skyline SHARED
${source_DIR}/skyline/kernel/types/KProcess.cpp
${source_DIR}/skyline/kernel/types/KThread.cpp
${source_DIR}/skyline/kernel/types/KSharedMemory.cpp
${source_DIR}/skyline/kernel/types/KTransferMemory.cpp
${source_DIR}/skyline/kernel/types/KPrivateMemory.cpp
${source_DIR}/skyline/kernel/services/serviceman.cpp
${source_DIR}/skyline/kernel/services/sm/sm.cpp
${source_DIR}/skyline/kernel/services/fatal/fatal.cpp
${source_DIR}/skyline/kernel/services/set/sys.cpp
${source_DIR}/skyline/kernel/services/apm/apm.cpp
${source_DIR}/skyline/kernel/services/am/appletOE.cpp
${source_DIR}/skyline/kernel/services/fatal/fatal.cpp
${source_DIR}/skyline/kernel/services/hid/hid.cpp
)
target_link_libraries(skyline fmt tinyxml2)
target_compile_options(skyline PRIVATE -Wno-c++17-extensions)
5 changes: 2 additions & 3 deletions app/src/main/cpp/skyline/common.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "common.h"
#include <tinyxml2.h>
#include <syslog.h>

namespace skyline {
Settings::Settings(const std::string &prefXml) {
Expand Down Expand Up @@ -34,7 +33,7 @@ namespace skyline {
return boolMap.at(key);
}

void Settings::List(std::shared_ptr<Logger>& logger) {
void Settings::List(std::shared_ptr<Logger> logger) {
for (auto& iter : stringMap)
logger->Write(Logger::Info, "Key: {}, Value: {}, Type: String", iter.first, GetString(iter.first));
for (auto& iter : boolMap)
Expand All @@ -56,7 +55,7 @@ namespace skyline {
logFile.flush();
}

void Logger::Write(const LogLevel level, const std::string &str) {
void Logger::Write(const LogLevel level, const std::string& str) {
#ifdef NDEBUG
if (level == Debug) return;
#endif
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/cpp/skyline/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ namespace skyline {
constexpr u64 BaseAddr = 0x8000000; //!< The address space base
constexpr u64 MapAddr = BaseAddr + 0x80000000; //!< The address of the map region
constexpr u64 BaseSize = 0x7FF8000000; //!< The size of the address space
constexpr u64 BaseEnd = BaseAddr + BaseSize; //!< The end of the address space
constexpr u64 MapSize = 0x1000000000; //!< The size of the map region
constexpr u64 TotalPhyMem = 0xF8000000; // ~4 GB of RAM
constexpr size_t DefStackSize = 0x1E8480; //!< The default amount of stack: 2 MB
Expand Down Expand Up @@ -231,7 +232,7 @@ namespace skyline {
/**
* @brief Writes all settings keys and values to syslog. This function is for development purposes.
*/
void List(std::shared_ptr<Logger> &logger);
void List(std::shared_ptr<Logger> logger);
};

// Predeclare some classes here as we use them in DeviceState
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/cpp/skyline/kernel/ipc.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#include <syslog.h>
#include <cstdlib>
#include "ipc.h"
#include "types/KProcess.h"

Expand All @@ -13,7 +11,7 @@ namespace skyline::kernel::ipc {

if (header->handle_desc) {
handleDesc = reinterpret_cast<HandleDescriptor *>(currPtr);
currPtr += sizeof(HandleDescriptor) + (handleDesc->send_pid ? sizeof(u8) : 0);
currPtr += sizeof(HandleDescriptor) + (handleDesc->send_pid ? sizeof(u64) : 0);
for (uint index = 0; handleDesc->copy_count > index; index++) {
copyHandles.push_back(*reinterpret_cast<handle_t *>(currPtr));
currPtr += sizeof(handle_t);
Expand Down Expand Up @@ -143,6 +141,8 @@ namespace skyline::kernel::ipc {
}
}

state.logger->Write(Logger::Debug, "Output: Raw Size: {}, Command ID: 0x{:X}, Copy Handles: {}, Move Handles: {}", u32(header->raw_sz), u32(payload->value), copyHandles.size(), moveHandles.size());

state.thisProcess->WriteMemory(tls.data(), state.thisThread->tls, constant::TlsIpcSize);
}
}
5 changes: 1 addition & 4 deletions app/src/main/cpp/skyline/kernel/ipc.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#pragma once

#include <cstdint>
#include <vector>
#include <array>
#include "../common.h"
#include <common.h>

namespace skyline::kernel::ipc {
/**
Expand Down Expand Up @@ -108,7 +106,6 @@ namespace skyline::kernel::ipc {
u32 address_0_31 : 32;

BufferDescriptorX(u64 address, u16 counter, u16 size) : size(size) {
// TODO: Test this, the AND mask might be the other way around
address_0_31 = static_cast<u32>(address & 0x7FFFFFFF80000000);
address_32_35 = static_cast<u16>(address & 0x78000000);
address_36_38 = static_cast<u16>(address & 0x7000000);
Expand Down
5 changes: 3 additions & 2 deletions app/src/main/cpp/skyline/kernel/services/am/appletOE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ namespace skyline::kernel::service::am {
}

void ICommonStateGetter::GetEventHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
messageEvent = state.thisProcess->NewHandle<type::KEvent>();
response.copyHandles.push_back(messageEvent->handle);
auto event = state.thisProcess->NewHandle<type::KEvent>();
messageEvent = event.item;
response.copyHandles.push_back(event.handle);
}

void ICommonStateGetter::GetCurrentFocusState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Expand Down
8 changes: 4 additions & 4 deletions app/src/main/cpp/skyline/kernel/services/am/appletOE.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#pragma once

#include "../base_service.h"
#include "../serviceman.h"
#include "../../types/KProcess.h"
#include "../../types/KEvent.h"
#include <kernel/services/base_service.h>
#include <kernel/services/serviceman.h>
#include <kernel/types/KProcess.h>
#include <kernel/types/KEvent.h>

namespace skyline::kernel::service::am {
/**
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/cpp/skyline/kernel/services/apm/apm.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#include "../base_service.h"
#include "../serviceman.h"
#include <kernel/services/base_service.h>
#include <kernel/services/serviceman.h>

namespace skyline::kernel::service::apm {
/**
Expand Down
8 changes: 6 additions & 2 deletions app/src/main/cpp/skyline/kernel/services/base_service.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#include "../../common.h"
#include "../ipc.h"
#include <common.h>
#include <kernel/ipc.h>
#include <functional>

#define SFunc(function) std::bind(&function, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)
Expand Down Expand Up @@ -29,6 +29,8 @@ namespace skyline::kernel::service {
am_IDisplayController,
am_ILibraryAppletCreator,
am_IDebugFunctions,
hid,
hid_IAppletResource,
};

/**
Expand All @@ -50,6 +52,8 @@ namespace skyline::kernel::service {
{"am:ILibraryAppletCreator", Service::am_ILibraryAppletCreator},
{"am:IApplicationFunctions", Service::am_IApplicationFunctions},
{"am:IDebugFunctions", Service::am_IDebugFunctions},
{"hid", Service::hid},
{"hid:IAppletResource", Service::hid_IAppletResource},
};

class ServiceManager;
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/cpp/skyline/kernel/services/fatal/fatal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

namespace skyline::kernel::service::fatal {
fatalU::fatalU(const DeviceState &state, ServiceManager& manager) : BaseService(state, manager, false, Service::fatal_u, {
{0x0, SFunc(fatalU::ThrowFatal)}
{0x0, SFunc(fatalU::ThrowFatal)},
{0x1, SFunc(fatalU::ThrowFatal)},
{0x2, SFunc(fatalU::ThrowFatal)}
}) {}

void fatalU::ThrowFatal(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
throw exception("A fatal error has caused emulation to stop");
throw exception(fmt::format("A fatal error with code: 0x{:X} has caused emulation to stop", *reinterpret_cast<u32*>(request.cmdArg)));
}
}
4 changes: 2 additions & 2 deletions app/src/main/cpp/skyline/kernel/services/fatal/fatal.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#include "../base_service.h"
#include "../serviceman.h"
#include <kernel/services/base_service.h>
#include <kernel/services/serviceman.h>

namespace skyline::kernel::service::fatal {
/**
Expand Down
21 changes: 21 additions & 0 deletions app/src/main/cpp/skyline/kernel/services/hid/hid.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "hid.h"
#include <os.h>

namespace skyline::kernel::service::hid {
hid::hid(const DeviceState &state, ServiceManager& manager) : BaseService(state, manager, false, Service::hid, {
{0x0, SFunc(hid::CreateAppletResource)}
}) {}

void hid::CreateAppletResource(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
resource = std::static_pointer_cast<IAppletResource>(manager.NewService(Service::hid_IAppletResource, session, response));
}

IAppletResource::IAppletResource(const DeviceState &state, ServiceManager& manager) : BaseService(state, manager, false, Service::hid_IAppletResource, {
{0x0, SFunc(IAppletResource::GetSharedMemoryHandle)}
}) {}

void IAppletResource::GetSharedMemoryHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
hidSharedMemory = state.os->MapSharedKernel(0, constant::hidSharedMemSize, memory::Permission(true, false, false), memory::Permission(true, true, false), memory::Type::SharedMemory);
response.copyHandles.push_back(state.thisProcess->InsertItem<type::KSharedMemory>(hidSharedMemory));
}
}
41 changes: 41 additions & 0 deletions app/src/main/cpp/skyline/kernel/services/hid/hid.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include <kernel/services/base_service.h>
#include <kernel/services/serviceman.h>
#include <kernel/types/KProcess.h>

namespace skyline::constant {
constexpr size_t hidSharedMemSize = 0x40000; //!< The size of HID Shared Memory (https://switchbrew.org/wiki/HID_Shared_Memory)
}

namespace skyline::kernel::service::hid {
/**
* @brief IAppletResource is used to get the handle to the HID shared memory (https://switchbrew.org/wiki/HID_services#IAppletResource)
*/
class IAppletResource : public BaseService {
public:
IAppletResource(const DeviceState &state, ServiceManager& manager);

std::shared_ptr<type::KSharedMemory> hidSharedMemory;

/**
* @brief This opens a handle to HID shared memory (https://switchbrew.org/wiki/HID_services#GetSharedMemoryHandle)
*/
void GetSharedMemoryHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};

/**
* @brief hid or Human Interface Device service is used to access input devices (https://switchbrew.org/wiki/HID_services#hid)
*/
class hid : public BaseService {
private:
std::shared_ptr<IAppletResource> resource{};
public:
hid(const DeviceState &state, ServiceManager& manager);

/**
* @brief This returns an IAppletResource (https://switchbrew.org/wiki/HID_services#CreateAppletResource)
*/
void CreateAppletResource(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}
16 changes: 12 additions & 4 deletions app/src/main/cpp/skyline/kernel/services/serviceman.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#include "serviceman.h"
#include "../types/KProcess.h"
#include <kernel/types/KProcess.h>
#include "sm/sm.h"
#include "set/sys.h"
#include "apm/apm.h"
#include "am/appletOE.h"
#include "fatal/fatal.h"
#include "hid/hid.h"

namespace skyline::kernel::service {
ServiceManager::ServiceManager(const DeviceState &state) : state(state) {}
Expand Down Expand Up @@ -58,6 +59,12 @@ namespace skyline::kernel::service {
case Service::am_IDebugFunctions:
serviceMap[serviceType] = std::make_shared<am::IDebugFunctions>(state, *this);
break;
case Service::hid:
serviceMap[serviceType] = std::make_shared<hid::hid>(state, *this);
break;
case Service::hid_IAppletResource:
serviceMap[serviceType] = std::make_shared<hid::IAppletResource>(state, *this);
break;
}
serviceObj = serviceMap[serviceType];
} else
Expand All @@ -67,17 +74,18 @@ namespace skyline::kernel::service {
}

handle_t ServiceManager::NewSession(const Service serviceType) {
return state.thisProcess->NewHandle<type::KSession>(GetService(serviceType), serviceType)->handle;
return state.thisProcess->NewHandle<type::KSession>(GetService(serviceType), serviceType).handle;
}

void ServiceManager::NewService(const Service serviceType, type::KSession &session, ipc::IpcResponse &response) {
std::shared_ptr<BaseService> ServiceManager::NewService(const Service serviceType, type::KSession &session, ipc::IpcResponse &response) {
auto serviceObject = GetService(serviceType);
if (response.isDomain) {
session.domainTable[++session.handleIndex] = serviceObject;
response.domainObjects.push_back(session.handleIndex);
} else
response.moveHandles.push_back(state.thisProcess->NewHandle<type::KSession>(serviceObject, serviceType)->handle);
response.moveHandles.push_back(state.thisProcess->NewHandle<type::KSession>(serviceObject, serviceType).handle);
state.logger->Write(Logger::Debug, "Service has been registered: \"{}\"", serviceObject->getName());
return serviceObject;
}

void ServiceManager::CloseSession(const handle_t handle) {
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/cpp/skyline/kernel/services/serviceman.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#pragma once

#include "../../nce.h"
#include <nce.h>
#include <kernel/types/KSession.h>
#include "base_service.h"
#include "../types/KSession.h"

namespace skyline::kernel::service {
/**
Expand Down Expand Up @@ -34,7 +34,7 @@ namespace skyline::kernel::service {
* @param session The session object of the command
* @param response The response object to write the handle or virtual handle to
*/
void NewService(const Service serviceType, type::KSession &session, ipc::IpcResponse &response);
std::shared_ptr<BaseService> NewService(const Service serviceType, type::KSession &session, ipc::IpcResponse &response);

/**
* @brief Closes an existing session to a service
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/cpp/skyline/kernel/services/set/sys.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "sys.h"
#include "../../types/KProcess.h"
#include <kernel/types/KProcess.h>

namespace skyline::kernel::service::set {
sys::sys(const DeviceState &state, ServiceManager& manager) : BaseService(state, manager, false, Service::set_sys, {{0x3, SFunc(sys::GetFirmwareVersion)}}) {}
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/cpp/skyline/kernel/services/set/sys.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#include "../base_service.h"
#include "../serviceman.h"
#include <kernel/services/base_service.h>
#include <kernel/services/serviceman.h>

namespace skyline::kernel::service::set {
/**
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/cpp/skyline/kernel/services/sm/sm.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#include "../base_service.h"
#include "../serviceman.h"
#include <kernel/services/base_service.h>
#include <kernel/services/serviceman.h>

namespace skyline::kernel::service::sm {
/**
Expand Down
Loading

0 comments on commit ec71735

Please sign in to comment.