Merge pull request #4341 from wwylele/kernel-global
Kernel: make a kernel instance and remove object ID counter from global state
This commit is contained in:
commit
6f1759c5bd
91 changed files with 620 additions and 443 deletions
|
@ -191,13 +191,13 @@ System::ResultStatus System::Init(EmuWindow& emu_window, u32 system_mode) {
|
||||||
rpc_server = std::make_unique<RPC::RPCServer>();
|
rpc_server = std::make_unique<RPC::RPCServer>();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
service_manager = std::make_shared<Service::SM::ServiceManager>();
|
service_manager = std::make_shared<Service::SM::ServiceManager>(*this);
|
||||||
shared_page_handler = std::make_shared<SharedPage::Handler>();
|
shared_page_handler = std::make_shared<SharedPage::Handler>();
|
||||||
archive_manager = std::make_unique<Service::FS::ArchiveManager>();
|
archive_manager = std::make_unique<Service::FS::ArchiveManager>(*this);
|
||||||
|
|
||||||
HW::Init();
|
HW::Init();
|
||||||
Kernel::Init(system_mode);
|
kernel = std::make_unique<Kernel::KernelSystem>(system_mode);
|
||||||
Service::Init(*this, service_manager);
|
Service::Init(*this);
|
||||||
GDBStub::Init();
|
GDBStub::Init();
|
||||||
|
|
||||||
ResultStatus result = VideoCore::Init(emu_window);
|
ResultStatus result = VideoCore::Init(emu_window);
|
||||||
|
@ -230,6 +230,14 @@ const Service::FS::ArchiveManager& System::ArchiveManager() const {
|
||||||
return *archive_manager;
|
return *archive_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Kernel::KernelSystem& System::Kernel() {
|
||||||
|
return *kernel;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Kernel::KernelSystem& System::Kernel() const {
|
||||||
|
return *kernel;
|
||||||
|
}
|
||||||
|
|
||||||
void System::RegisterSoftwareKeyboard(std::shared_ptr<Frontend::SoftwareKeyboard> swkbd) {
|
void System::RegisterSoftwareKeyboard(std::shared_ptr<Frontend::SoftwareKeyboard> swkbd) {
|
||||||
registered_swkbd = std::move(swkbd);
|
registered_swkbd = std::move(swkbd);
|
||||||
}
|
}
|
||||||
|
@ -248,7 +256,7 @@ void System::Shutdown() {
|
||||||
GDBStub::Shutdown();
|
GDBStub::Shutdown();
|
||||||
VideoCore::Shutdown();
|
VideoCore::Shutdown();
|
||||||
Service::Shutdown();
|
Service::Shutdown();
|
||||||
Kernel::Shutdown();
|
kernel.reset();
|
||||||
HW::Shutdown();
|
HW::Shutdown();
|
||||||
telemetry_session.reset();
|
telemetry_session.reset();
|
||||||
#ifdef ENABLE_SCRIPTING
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
|
|
@ -36,6 +36,10 @@ class ArchiveManager;
|
||||||
}
|
}
|
||||||
} // namespace Service
|
} // namespace Service
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
class KernelSystem;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
class System {
|
class System {
|
||||||
|
@ -167,6 +171,12 @@ public:
|
||||||
/// Gets a const reference to the archive manager
|
/// Gets a const reference to the archive manager
|
||||||
const Service::FS::ArchiveManager& ArchiveManager() const;
|
const Service::FS::ArchiveManager& ArchiveManager() const;
|
||||||
|
|
||||||
|
/// Gets a reference to the kernel
|
||||||
|
Kernel::KernelSystem& Kernel();
|
||||||
|
|
||||||
|
/// Gets a const reference to the kernel
|
||||||
|
const Kernel::KernelSystem& Kernel() const;
|
||||||
|
|
||||||
PerfStats perf_stats;
|
PerfStats perf_stats;
|
||||||
FrameLimiter frame_limiter;
|
FrameLimiter frame_limiter;
|
||||||
|
|
||||||
|
@ -241,6 +251,8 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<Service::FS::ArchiveManager> archive_manager;
|
std::unique_ptr<Service::FS::ArchiveManager> archive_manager;
|
||||||
|
|
||||||
|
std::unique_ptr<Kernel::KernelSystem> kernel;
|
||||||
|
|
||||||
static System s_instance;
|
static System s_instance;
|
||||||
|
|
||||||
ResultStatus status = ResultStatus::Success;
|
ResultStatus status = ResultStatus::Success;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/hle/applets/erreula.h"
|
#include "core/hle/applets/erreula.h"
|
||||||
#include "core/hle/service/apt/apt.h"
|
#include "core/hle/service/apt/apt.h"
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ ResultCode ErrEula::ReceiveParameter(const Service::APT::MessageParameter& param
|
||||||
// Allocate a heap block of the required size for this applet.
|
// Allocate a heap block of the required size for this applet.
|
||||||
heap_memory = std::make_shared<std::vector<u8>>(capture_info.size);
|
heap_memory = std::make_shared<std::vector<u8>>(capture_info.size);
|
||||||
// Create a SharedMemory that directly points to this heap block.
|
// Create a SharedMemory that directly points to this heap block.
|
||||||
framebuffer_memory = Kernel::SharedMemory::CreateForApplet(
|
framebuffer_memory = Core::System::GetInstance().Kernel().CreateSharedMemoryForApplet(
|
||||||
heap_memory, 0, capture_info.size, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite,
|
heap_memory, 0, capture_info.size, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite,
|
||||||
"ErrEula Memory");
|
"ErrEula Memory");
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/hle/applets/mii_selector.h"
|
#include "core/hle/applets/mii_selector.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/shared_memory.h"
|
#include "core/hle/kernel/shared_memory.h"
|
||||||
|
@ -37,7 +38,7 @@ ResultCode MiiSelector::ReceiveParameter(const Service::APT::MessageParameter& p
|
||||||
// Allocate a heap block of the required size for this applet.
|
// Allocate a heap block of the required size for this applet.
|
||||||
heap_memory = std::make_shared<std::vector<u8>>(capture_info.size);
|
heap_memory = std::make_shared<std::vector<u8>>(capture_info.size);
|
||||||
// Create a SharedMemory that directly points to this heap block.
|
// Create a SharedMemory that directly points to this heap block.
|
||||||
framebuffer_memory = Kernel::SharedMemory::CreateForApplet(
|
framebuffer_memory = Core::System::GetInstance().Kernel().CreateSharedMemoryForApplet(
|
||||||
heap_memory, 0, capture_info.size, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite,
|
heap_memory, 0, capture_info.size, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite,
|
||||||
"MiiSelector Memory");
|
"MiiSelector Memory");
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/hle/applets/mint.h"
|
#include "core/hle/applets/mint.h"
|
||||||
#include "core/hle/service/apt/apt.h"
|
#include "core/hle/service/apt/apt.h"
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ ResultCode Mint::ReceiveParameter(const Service::APT::MessageParameter& paramete
|
||||||
// Allocate a heap block of the required size for this applet.
|
// Allocate a heap block of the required size for this applet.
|
||||||
heap_memory = std::make_shared<std::vector<u8>>(capture_info.size);
|
heap_memory = std::make_shared<std::vector<u8>>(capture_info.size);
|
||||||
// Create a SharedMemory that directly points to this heap block.
|
// Create a SharedMemory that directly points to this heap block.
|
||||||
framebuffer_memory = Kernel::SharedMemory::CreateForApplet(
|
framebuffer_memory = Core::System::GetInstance().Kernel().CreateSharedMemoryForApplet(
|
||||||
heap_memory, 0, capture_info.size, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite,
|
heap_memory, 0, capture_info.size, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite,
|
||||||
"Mint Memory");
|
"Mint Memory");
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/hle/applets/swkbd.h"
|
#include "core/hle/applets/swkbd.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/shared_memory.h"
|
#include "core/hle/kernel/shared_memory.h"
|
||||||
|
@ -41,7 +42,7 @@ ResultCode SoftwareKeyboard::ReceiveParameter(Service::APT::MessageParameter con
|
||||||
// Allocate a heap block of the required size for this applet.
|
// Allocate a heap block of the required size for this applet.
|
||||||
heap_memory = std::make_shared<std::vector<u8>>(capture_info.size);
|
heap_memory = std::make_shared<std::vector<u8>>(capture_info.size);
|
||||||
// Create a SharedMemory that directly points to this heap block.
|
// Create a SharedMemory that directly points to this heap block.
|
||||||
framebuffer_memory = Kernel::SharedMemory::CreateForApplet(
|
framebuffer_memory = Core::System::GetInstance().Kernel().CreateSharedMemoryForApplet(
|
||||||
heap_memory, 0, capture_info.size, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite,
|
heap_memory, 0, capture_info.size, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite,
|
||||||
"SoftwareKeyboard Memory");
|
"SoftwareKeyboard Memory");
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/hle/kernel/address_arbiter.h"
|
#include "core/hle/kernel/address_arbiter.h"
|
||||||
#include "core/hle/kernel/errors.h"
|
#include "core/hle/kernel/errors.h"
|
||||||
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/thread.h"
|
#include "core/hle/kernel/thread.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
|
@ -64,11 +65,11 @@ SharedPtr<Thread> AddressArbiter::ResumeHighestPriorityThread(VAddr address) {
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddressArbiter::AddressArbiter() {}
|
AddressArbiter::AddressArbiter(KernelSystem& kernel) : Object(kernel) {}
|
||||||
AddressArbiter::~AddressArbiter() {}
|
AddressArbiter::~AddressArbiter() {}
|
||||||
|
|
||||||
SharedPtr<AddressArbiter> AddressArbiter::Create(std::string name) {
|
SharedPtr<AddressArbiter> KernelSystem::CreateAddressArbiter(std::string name) {
|
||||||
SharedPtr<AddressArbiter> address_arbiter(new AddressArbiter);
|
SharedPtr<AddressArbiter> address_arbiter(new AddressArbiter(*this));
|
||||||
|
|
||||||
address_arbiter->name = std::move(name);
|
address_arbiter->name = std::move(name);
|
||||||
|
|
||||||
|
|
|
@ -31,14 +31,6 @@ enum class ArbitrationType : u32 {
|
||||||
|
|
||||||
class AddressArbiter final : public Object {
|
class AddressArbiter final : public Object {
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* Creates an address arbiter.
|
|
||||||
*
|
|
||||||
* @param name Optional name used for debugging.
|
|
||||||
* @returns The created AddressArbiter.
|
|
||||||
*/
|
|
||||||
static SharedPtr<AddressArbiter> Create(std::string name = "Unknown");
|
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "Arbiter";
|
return "Arbiter";
|
||||||
}
|
}
|
||||||
|
@ -57,7 +49,7 @@ public:
|
||||||
s32 value, u64 nanoseconds);
|
s32 value, u64 nanoseconds);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AddressArbiter();
|
explicit AddressArbiter(KernelSystem& kernel);
|
||||||
~AddressArbiter() override;
|
~AddressArbiter() override;
|
||||||
|
|
||||||
/// Puts the thread to wait on the specified arbitration address under this address arbiter.
|
/// Puts the thread to wait on the specified arbitration address under this address arbiter.
|
||||||
|
@ -72,6 +64,8 @@ private:
|
||||||
|
|
||||||
/// Threads waiting for the address arbiter to be signaled.
|
/// Threads waiting for the address arbiter to be signaled.
|
||||||
std::vector<SharedPtr<Thread>> waiting_threads;
|
std::vector<SharedPtr<Thread>> waiting_threads;
|
||||||
|
|
||||||
|
friend class KernelSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
ClientPort::ClientPort() = default;
|
ClientPort::ClientPort(KernelSystem& kernel) : kernel(kernel), Object(kernel) {}
|
||||||
ClientPort::~ClientPort() = default;
|
ClientPort::~ClientPort() = default;
|
||||||
|
|
||||||
ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
|
ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
|
||||||
|
@ -26,7 +26,7 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
|
||||||
active_sessions++;
|
active_sessions++;
|
||||||
|
|
||||||
// Create a new session pair, let the created sessions inherit the parent port's HLE handler.
|
// Create a new session pair, let the created sessions inherit the parent port's HLE handler.
|
||||||
auto sessions = ServerSession::CreateSessionPair(server_port->GetName(), this);
|
auto sessions = kernel.CreateSessionPair(server_port->GetName(), this);
|
||||||
|
|
||||||
if (server_port->hle_handler)
|
if (server_port->hle_handler)
|
||||||
server_port->hle_handler->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions));
|
server_port->hle_handler->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions));
|
||||||
|
|
|
@ -48,13 +48,16 @@ public:
|
||||||
void ConnectionClosed();
|
void ConnectionClosed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClientPort();
|
explicit ClientPort(KernelSystem& kernel);
|
||||||
~ClientPort() override;
|
~ClientPort() override;
|
||||||
|
|
||||||
|
KernelSystem& kernel;
|
||||||
SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port.
|
SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port.
|
||||||
u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have
|
u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have
|
||||||
u32 active_sessions = 0; ///< Number of currently open sessions to this port
|
u32 active_sessions = 0; ///< Number of currently open sessions to this port
|
||||||
std::string name; ///< Name of client port (optional)
|
std::string name; ///< Name of client port (optional)
|
||||||
|
|
||||||
|
friend class KernelSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
ClientSession::ClientSession() = default;
|
ClientSession::ClientSession(KernelSystem& kernel) : Object(kernel) {}
|
||||||
ClientSession::~ClientSession() {
|
ClientSession::~ClientSession() {
|
||||||
// This destructor will be called automatically when the last ClientSession handle is closed by
|
// This destructor will be called automatically when the last ClientSession handle is closed by
|
||||||
// the emulated application.
|
// the emulated application.
|
||||||
|
|
|
@ -12,13 +12,12 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
class ServerSession;
|
|
||||||
class Session;
|
class Session;
|
||||||
class Thread;
|
class Thread;
|
||||||
|
|
||||||
class ClientSession final : public Object {
|
class ClientSession final : public Object {
|
||||||
public:
|
public:
|
||||||
friend class ServerSession;
|
friend class KernelSystem;
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "ClientSession";
|
return "ClientSession";
|
||||||
|
@ -46,7 +45,7 @@ public:
|
||||||
std::shared_ptr<Session> parent;
|
std::shared_ptr<Session> parent;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClientSession();
|
explicit ClientSession(KernelSystem& kernel);
|
||||||
~ClientSession() override;
|
~ClientSession() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,16 +7,16 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "core/hle/kernel/event.h"
|
#include "core/hle/kernel/event.h"
|
||||||
#include "core/hle/kernel/object.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/thread.h"
|
#include "core/hle/kernel/thread.h"
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
Event::Event() {}
|
Event::Event(KernelSystem& kernel) : WaitObject(kernel) {}
|
||||||
Event::~Event() {}
|
Event::~Event() {}
|
||||||
|
|
||||||
SharedPtr<Event> Event::Create(ResetType reset_type, std::string name) {
|
SharedPtr<Event> KernelSystem::CreateEvent(ResetType reset_type, std::string name) {
|
||||||
SharedPtr<Event> evt(new Event);
|
SharedPtr<Event> evt(new Event(*this));
|
||||||
|
|
||||||
evt->signaled = false;
|
evt->signaled = false;
|
||||||
evt->reset_type = reset_type;
|
evt->reset_type = reset_type;
|
||||||
|
|
|
@ -12,13 +12,6 @@ namespace Kernel {
|
||||||
|
|
||||||
class Event final : public WaitObject {
|
class Event final : public WaitObject {
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* Creates an event
|
|
||||||
* @param reset_type ResetType describing how to create event
|
|
||||||
* @param name Optional name of event
|
|
||||||
*/
|
|
||||||
static SharedPtr<Event> Create(ResetType reset_type, std::string name = "Unknown");
|
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "Event";
|
return "Event";
|
||||||
}
|
}
|
||||||
|
@ -47,13 +40,15 @@ public:
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Event();
|
explicit Event(KernelSystem& kernel);
|
||||||
~Event() override;
|
~Event() override;
|
||||||
|
|
||||||
ResetType reset_type; ///< Current ResetType
|
ResetType reset_type; ///< Current ResetType
|
||||||
|
|
||||||
bool signaled; ///< Whether the event has already been signaled
|
bool signaled; ///< Whether the event has already been signaled
|
||||||
std::string name; ///< Name of event (optional)
|
std::string name; ///< Name of event (optional)
|
||||||
|
|
||||||
|
friend class KernelSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/hle/kernel/event.h"
|
#include "core/hle/kernel/event.h"
|
||||||
#include "core/hle/kernel/handle_table.h"
|
#include "core/hle/kernel/handle_table.h"
|
||||||
#include "core/hle/kernel/hle_ipc.h"
|
#include "core/hle/kernel/hle_ipc.h"
|
||||||
|
@ -55,7 +56,8 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
|
||||||
cmd_buff.size() * sizeof(u32));
|
cmd_buff.size() * sizeof(u32));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto event = Kernel::Event::Create(Kernel::ResetType::OneShot, "HLE Pause Event: " + reason);
|
auto event = Core::System::GetInstance().Kernel().CreateEvent(Kernel::ResetType::OneShot,
|
||||||
|
"HLE Pause Event: " + reason);
|
||||||
thread->status = ThreadStatus::WaitHleEvent;
|
thread->status = ThreadStatus::WaitHleEvent;
|
||||||
thread->wait_objects = {event};
|
thread->wait_objects = {event};
|
||||||
event->AddWaitingThread(thread);
|
event->AddWaitingThread(thread);
|
||||||
|
|
|
@ -14,34 +14,41 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
std::atomic<u32> Object::next_object_id{0};
|
|
||||||
|
|
||||||
/// Initialize the kernel
|
/// Initialize the kernel
|
||||||
void Init(u32 system_mode) {
|
KernelSystem::KernelSystem(u32 system_mode) {
|
||||||
ConfigMem::Init();
|
ConfigMem::Init();
|
||||||
|
|
||||||
Kernel::MemoryInit(system_mode);
|
Kernel::MemoryInit(system_mode);
|
||||||
|
|
||||||
Kernel::ResourceLimitsInit();
|
resource_limits = std::make_unique<ResourceLimitList>(*this);
|
||||||
Kernel::ThreadingInit();
|
Kernel::ThreadingInit();
|
||||||
Kernel::TimersInit();
|
Kernel::TimersInit();
|
||||||
|
|
||||||
Object::next_object_id = 0;
|
|
||||||
// TODO(Subv): Start the process ids from 10 for now, as lower PIDs are
|
// TODO(Subv): Start the process ids from 10 for now, as lower PIDs are
|
||||||
// reserved for low-level services
|
// reserved for low-level services
|
||||||
Process::next_process_id = 10;
|
Process::next_process_id = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shutdown the kernel
|
/// Shutdown the kernel
|
||||||
void Shutdown() {
|
KernelSystem::~KernelSystem() {
|
||||||
g_handle_table.Clear(); // Free all kernel objects
|
g_handle_table.Clear(); // Free all kernel objects
|
||||||
|
|
||||||
Kernel::ThreadingShutdown();
|
Kernel::ThreadingShutdown();
|
||||||
g_current_process = nullptr;
|
g_current_process = nullptr;
|
||||||
|
|
||||||
Kernel::TimersShutdown();
|
Kernel::TimersShutdown();
|
||||||
Kernel::ResourceLimitsShutdown();
|
|
||||||
Kernel::MemoryShutdown();
|
Kernel::MemoryShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResourceLimitList& KernelSystem::ResourceLimit() {
|
||||||
|
return *resource_limits;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ResourceLimitList& KernelSystem::ResourceLimit() const {
|
||||||
|
return *resource_limits;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 KernelSystem::GenerateObjectID() {
|
||||||
|
return next_object_id++;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -4,14 +4,185 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <boost/smart_ptr/intrusive_ptr.hpp>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
/// Initialize the kernel with the specified system mode.
|
class AddressArbiter;
|
||||||
void Init(u32 system_mode);
|
class Event;
|
||||||
|
class Mutex;
|
||||||
|
class CodeSet;
|
||||||
|
class Process;
|
||||||
|
class Thread;
|
||||||
|
class Semaphore;
|
||||||
|
class Timer;
|
||||||
|
class ClientPort;
|
||||||
|
class ServerPort;
|
||||||
|
class ClientSession;
|
||||||
|
class ServerSession;
|
||||||
|
class ResourceLimitList;
|
||||||
|
class SharedMemory;
|
||||||
|
|
||||||
/// Shutdown the kernel
|
enum class ResetType {
|
||||||
void Shutdown();
|
OneShot,
|
||||||
|
Sticky,
|
||||||
|
Pulse,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Permissions for mapped shared memory blocks
|
||||||
|
enum class MemoryPermission : u32 {
|
||||||
|
None = 0,
|
||||||
|
Read = (1u << 0),
|
||||||
|
Write = (1u << 1),
|
||||||
|
ReadWrite = (Read | Write),
|
||||||
|
Execute = (1u << 2),
|
||||||
|
ReadExecute = (Read | Execute),
|
||||||
|
WriteExecute = (Write | Execute),
|
||||||
|
ReadWriteExecute = (Read | Write | Execute),
|
||||||
|
DontCare = (1u << 28)
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class MemoryRegion : u16 {
|
||||||
|
APPLICATION = 1,
|
||||||
|
SYSTEM = 2,
|
||||||
|
BASE = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using SharedPtr = boost::intrusive_ptr<T>;
|
||||||
|
|
||||||
|
class KernelSystem {
|
||||||
|
public:
|
||||||
|
explicit KernelSystem(u32 system_mode);
|
||||||
|
~KernelSystem();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an address arbiter.
|
||||||
|
*
|
||||||
|
* @param name Optional name used for debugging.
|
||||||
|
* @returns The created AddressArbiter.
|
||||||
|
*/
|
||||||
|
SharedPtr<AddressArbiter> CreateAddressArbiter(std::string name = "Unknown");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an event
|
||||||
|
* @param reset_type ResetType describing how to create event
|
||||||
|
* @param name Optional name of event
|
||||||
|
*/
|
||||||
|
SharedPtr<Event> CreateEvent(ResetType reset_type, std::string name = "Unknown");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a mutex.
|
||||||
|
* @param initial_locked Specifies if the mutex should be locked initially
|
||||||
|
* @param name Optional name of mutex
|
||||||
|
* @return Pointer to new Mutex object
|
||||||
|
*/
|
||||||
|
SharedPtr<Mutex> CreateMutex(bool initial_locked, std::string name = "Unknown");
|
||||||
|
|
||||||
|
SharedPtr<CodeSet> CreateCodeSet(std::string name, u64 program_id);
|
||||||
|
|
||||||
|
SharedPtr<Process> CreateProcess(SharedPtr<CodeSet> code_set);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a new thread. The new thread is immediately scheduled
|
||||||
|
* @param name The friendly name desired for the thread
|
||||||
|
* @param entry_point The address at which the thread should start execution
|
||||||
|
* @param priority The thread's priority
|
||||||
|
* @param arg User data to pass to the thread
|
||||||
|
* @param processor_id The ID(s) of the processors on which the thread is desired to be run
|
||||||
|
* @param stack_top The address of the thread's stack top
|
||||||
|
* @param owner_process The parent process for the thread
|
||||||
|
* @return A shared pointer to the newly created thread
|
||||||
|
*/
|
||||||
|
ResultVal<SharedPtr<Thread>> CreateThread(std::string name, VAddr entry_point, u32 priority,
|
||||||
|
u32 arg, s32 processor_id, VAddr stack_top,
|
||||||
|
SharedPtr<Process> owner_process);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a semaphore.
|
||||||
|
* @param initial_count Number of slots reserved for other threads
|
||||||
|
* @param max_count Maximum number of slots the semaphore can have
|
||||||
|
* @param name Optional name of semaphore
|
||||||
|
* @return The created semaphore
|
||||||
|
*/
|
||||||
|
ResultVal<SharedPtr<Semaphore>> CreateSemaphore(s32 initial_count, s32 max_count,
|
||||||
|
std::string name = "Unknown");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a timer
|
||||||
|
* @param reset_type ResetType describing how to create the timer
|
||||||
|
* @param name Optional name of timer
|
||||||
|
* @return The created Timer
|
||||||
|
*/
|
||||||
|
SharedPtr<Timer> CreateTimer(ResetType reset_type, std::string name = "Unknown");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a pair of ServerPort and an associated ClientPort.
|
||||||
|
*
|
||||||
|
* @param max_sessions Maximum number of sessions to the port
|
||||||
|
* @param name Optional name of the ports
|
||||||
|
* @return The created port tuple
|
||||||
|
*/
|
||||||
|
std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> CreatePortPair(
|
||||||
|
u32 max_sessions, std::string name = "UnknownPort");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a pair of ServerSession and an associated ClientSession.
|
||||||
|
* @param name Optional name of the ports.
|
||||||
|
* @param client_port Optional The ClientPort that spawned this session.
|
||||||
|
* @return The created session tuple
|
||||||
|
*/
|
||||||
|
std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>> CreateSessionPair(
|
||||||
|
const std::string& name = "Unknown", SharedPtr<ClientPort> client_port = nullptr);
|
||||||
|
|
||||||
|
ResourceLimitList& ResourceLimit();
|
||||||
|
const ResourceLimitList& ResourceLimit() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a shared memory object.
|
||||||
|
* @param owner_process Process that created this shared memory object.
|
||||||
|
* @param size Size of the memory block. Must be page-aligned.
|
||||||
|
* @param permissions Permission restrictions applied to the process which created the block.
|
||||||
|
* @param other_permissions Permission restrictions applied to other processes mapping the
|
||||||
|
* block.
|
||||||
|
* @param address The address from which to map the Shared Memory.
|
||||||
|
* @param region If the address is 0, the shared memory will be allocated in this region of the
|
||||||
|
* linear heap.
|
||||||
|
* @param name Optional object name, used for debugging purposes.
|
||||||
|
*/
|
||||||
|
SharedPtr<SharedMemory> CreateSharedMemory(SharedPtr<Process> owner_process, u32 size,
|
||||||
|
MemoryPermission permissions,
|
||||||
|
MemoryPermission other_permissions,
|
||||||
|
VAddr address = 0,
|
||||||
|
MemoryRegion region = MemoryRegion::BASE,
|
||||||
|
std::string name = "Unknown");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a shared memory object from a block of memory managed by an HLE applet.
|
||||||
|
* @param heap_block Heap block of the HLE applet.
|
||||||
|
* @param offset The offset into the heap block that the SharedMemory will map.
|
||||||
|
* @param size Size of the memory block. Must be page-aligned.
|
||||||
|
* @param permissions Permission restrictions applied to the process which created the block.
|
||||||
|
* @param other_permissions Permission restrictions applied to other processes mapping the
|
||||||
|
* block.
|
||||||
|
* @param name Optional object name, used for debugging purposes.
|
||||||
|
*/
|
||||||
|
SharedPtr<SharedMemory> CreateSharedMemoryForApplet(std::shared_ptr<std::vector<u8>> heap_block,
|
||||||
|
u32 offset, u32 size,
|
||||||
|
MemoryPermission permissions,
|
||||||
|
MemoryPermission other_permissions,
|
||||||
|
std::string name = "Unknown Applet");
|
||||||
|
|
||||||
|
u32 GenerateObjectID();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<ResourceLimitList> resource_limits;
|
||||||
|
std::atomic<u32> next_object_id{0};
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -24,11 +24,11 @@ void ReleaseThreadMutexes(Thread* thread) {
|
||||||
thread->held_mutexes.clear();
|
thread->held_mutexes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Mutex::Mutex() {}
|
Mutex::Mutex(KernelSystem& kernel) : WaitObject(kernel) {}
|
||||||
Mutex::~Mutex() {}
|
Mutex::~Mutex() {}
|
||||||
|
|
||||||
SharedPtr<Mutex> Mutex::Create(bool initial_locked, std::string name) {
|
SharedPtr<Mutex> KernelSystem::CreateMutex(bool initial_locked, std::string name) {
|
||||||
SharedPtr<Mutex> mutex(new Mutex);
|
SharedPtr<Mutex> mutex(new Mutex(*this));
|
||||||
|
|
||||||
mutex->lock_count = 0;
|
mutex->lock_count = 0;
|
||||||
mutex->name = std::move(name);
|
mutex->name = std::move(name);
|
||||||
|
|
|
@ -16,14 +16,6 @@ class Thread;
|
||||||
|
|
||||||
class Mutex final : public WaitObject {
|
class Mutex final : public WaitObject {
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* Creates a mutex.
|
|
||||||
* @param initial_locked Specifies if the mutex should be locked initially
|
|
||||||
* @param name Optional name of mutex
|
|
||||||
* @return Pointer to new Mutex object
|
|
||||||
*/
|
|
||||||
static SharedPtr<Mutex> Create(bool initial_locked, std::string name = "Unknown");
|
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "Mutex";
|
return "Mutex";
|
||||||
}
|
}
|
||||||
|
@ -61,8 +53,10 @@ public:
|
||||||
ResultCode Release(Thread* thread);
|
ResultCode Release(Thread* thread);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Mutex();
|
explicit Mutex(KernelSystem& kernel);
|
||||||
~Mutex() override;
|
~Mutex() override;
|
||||||
|
|
||||||
|
friend class KernelSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,10 +3,13 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/object.h"
|
#include "core/hle/kernel/object.h"
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
Object::Object(KernelSystem& kernel) : object_id{kernel.GenerateObjectID()} {}
|
||||||
|
|
||||||
Object::~Object() = default;
|
Object::~Object() = default;
|
||||||
|
|
||||||
bool Object::IsWaitable() const {
|
bool Object::IsWaitable() const {
|
||||||
|
|
|
@ -6,13 +6,13 @@
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <boost/smart_ptr/intrusive_ptr.hpp>
|
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "core/hle/kernel/kernel.h"
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
class KernelSystem;
|
||||||
|
|
||||||
using Handle = u32;
|
using Handle = u32;
|
||||||
|
|
||||||
enum class HandleType : u32 {
|
enum class HandleType : u32 {
|
||||||
|
@ -37,14 +37,9 @@ enum {
|
||||||
DEFAULT_STACK_SIZE = 0x4000,
|
DEFAULT_STACK_SIZE = 0x4000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ResetType {
|
|
||||||
OneShot,
|
|
||||||
Sticky,
|
|
||||||
Pulse,
|
|
||||||
};
|
|
||||||
|
|
||||||
class Object : NonCopyable {
|
class Object : NonCopyable {
|
||||||
public:
|
public:
|
||||||
|
explicit Object(KernelSystem& kernel);
|
||||||
virtual ~Object();
|
virtual ~Object();
|
||||||
|
|
||||||
/// Returns a unique identifier for the object. For debugging purposes only.
|
/// Returns a unique identifier for the object. For debugging purposes only.
|
||||||
|
@ -66,15 +61,12 @@ public:
|
||||||
*/
|
*/
|
||||||
bool IsWaitable() const;
|
bool IsWaitable() const;
|
||||||
|
|
||||||
public:
|
|
||||||
static std::atomic<u32> next_object_id;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend void intrusive_ptr_add_ref(Object*);
|
friend void intrusive_ptr_add_ref(Object*);
|
||||||
friend void intrusive_ptr_release(Object*);
|
friend void intrusive_ptr_release(Object*);
|
||||||
|
|
||||||
std::atomic<u32> ref_count{0};
|
std::atomic<u32> ref_count{0};
|
||||||
std::atomic<u32> object_id{next_object_id++};
|
std::atomic<u32> object_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Special functions used by boost::instrusive_ptr to do automatic ref-counting
|
// Special functions used by boost::instrusive_ptr to do automatic ref-counting
|
||||||
|
@ -88,9 +80,6 @@ inline void intrusive_ptr_release(Object* object) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using SharedPtr = boost::intrusive_ptr<T>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to downcast the given Object pointer to a pointer to T.
|
* Attempts to downcast the given Object pointer to a pointer to T.
|
||||||
* @return Derived pointer to the object, or `nullptr` if `object` isn't of type T.
|
* @return Derived pointer to the object, or `nullptr` if `object` isn't of type T.
|
||||||
|
|
|
@ -20,8 +20,8 @@ namespace Kernel {
|
||||||
// Lists all processes that exist in the current session.
|
// Lists all processes that exist in the current session.
|
||||||
static std::vector<SharedPtr<Process>> process_list;
|
static std::vector<SharedPtr<Process>> process_list;
|
||||||
|
|
||||||
SharedPtr<CodeSet> CodeSet::Create(std::string name, u64 program_id) {
|
SharedPtr<CodeSet> KernelSystem::CreateCodeSet(std::string name, u64 program_id) {
|
||||||
SharedPtr<CodeSet> codeset(new CodeSet);
|
SharedPtr<CodeSet> codeset(new CodeSet(*this));
|
||||||
|
|
||||||
codeset->name = std::move(name);
|
codeset->name = std::move(name);
|
||||||
codeset->program_id = program_id;
|
codeset->program_id = program_id;
|
||||||
|
@ -29,13 +29,13 @@ SharedPtr<CodeSet> CodeSet::Create(std::string name, u64 program_id) {
|
||||||
return codeset;
|
return codeset;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeSet::CodeSet() {}
|
CodeSet::CodeSet(KernelSystem& kernel) : Object(kernel) {}
|
||||||
CodeSet::~CodeSet() {}
|
CodeSet::~CodeSet() {}
|
||||||
|
|
||||||
u32 Process::next_process_id;
|
u32 Process::next_process_id;
|
||||||
|
|
||||||
SharedPtr<Process> Process::Create(SharedPtr<CodeSet> code_set) {
|
SharedPtr<Process> KernelSystem::CreateProcess(SharedPtr<CodeSet> code_set) {
|
||||||
SharedPtr<Process> process(new Process);
|
SharedPtr<Process> process(new Process(*this));
|
||||||
|
|
||||||
process->codeset = std::move(code_set);
|
process->codeset = std::move(code_set);
|
||||||
process->flags.raw = 0;
|
process->flags.raw = 0;
|
||||||
|
@ -155,7 +155,7 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) {
|
||||||
status = ProcessStatus::Running;
|
status = ProcessStatus::Running;
|
||||||
|
|
||||||
vm_manager.LogLayout(Log::Level::Debug);
|
vm_manager.LogLayout(Log::Level::Debug);
|
||||||
Kernel::SetupMainThread(codeset->entrypoint, main_thread_priority, this);
|
Kernel::SetupMainThread(kernel, codeset->entrypoint, main_thread_priority, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
VAddr Process::GetLinearHeapAreaAddress() const {
|
VAddr Process::GetLinearHeapAreaAddress() const {
|
||||||
|
@ -304,7 +304,7 @@ ResultCode Process::LinearFree(VAddr target, u32 size) {
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::Process::Process() {}
|
Kernel::Process::Process(KernelSystem& kernel) : Object(kernel), kernel(kernel) {}
|
||||||
Kernel::Process::~Process() {}
|
Kernel::Process::~Process() {}
|
||||||
|
|
||||||
void ClearProcessList() {
|
void ClearProcessList() {
|
||||||
|
|
|
@ -26,12 +26,6 @@ struct AddressMapping {
|
||||||
bool unk_flag;
|
bool unk_flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class MemoryRegion : u16 {
|
|
||||||
APPLICATION = 1,
|
|
||||||
SYSTEM = 2,
|
|
||||||
BASE = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
union ProcessFlags {
|
union ProcessFlags {
|
||||||
u16 raw;
|
u16 raw;
|
||||||
|
|
||||||
|
@ -62,8 +56,6 @@ struct CodeSet final : public Object {
|
||||||
u32 size = 0;
|
u32 size = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
static SharedPtr<CodeSet> Create(std::string name, u64 program_id);
|
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "CodeSet";
|
return "CodeSet";
|
||||||
}
|
}
|
||||||
|
@ -111,14 +103,14 @@ struct CodeSet final : public Object {
|
||||||
u64 program_id;
|
u64 program_id;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CodeSet();
|
explicit CodeSet(KernelSystem& kernel);
|
||||||
~CodeSet() override;
|
~CodeSet() override;
|
||||||
|
|
||||||
|
friend class KernelSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Process final : public Object {
|
class Process final : public Object {
|
||||||
public:
|
public:
|
||||||
static SharedPtr<Process> Create(SharedPtr<CodeSet> code_set);
|
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "Process";
|
return "Process";
|
||||||
}
|
}
|
||||||
|
@ -201,8 +193,11 @@ public:
|
||||||
ResultCode LinearFree(VAddr target, u32 size);
|
ResultCode LinearFree(VAddr target, u32 size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Process();
|
explicit Process(Kernel::KernelSystem& kernel);
|
||||||
~Process() override;
|
~Process() override;
|
||||||
|
|
||||||
|
friend class KernelSystem;
|
||||||
|
KernelSystem& kernel;
|
||||||
};
|
};
|
||||||
|
|
||||||
void ClearProcessList();
|
void ClearProcessList();
|
||||||
|
|
|
@ -9,19 +9,17 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
static SharedPtr<ResourceLimit> resource_limits[4];
|
ResourceLimit::ResourceLimit(KernelSystem& kernel) : Object(kernel) {}
|
||||||
|
|
||||||
ResourceLimit::ResourceLimit() {}
|
|
||||||
ResourceLimit::~ResourceLimit() {}
|
ResourceLimit::~ResourceLimit() {}
|
||||||
|
|
||||||
SharedPtr<ResourceLimit> ResourceLimit::Create(std::string name) {
|
SharedPtr<ResourceLimit> ResourceLimit::Create(KernelSystem& kernel, std::string name) {
|
||||||
SharedPtr<ResourceLimit> resource_limit(new ResourceLimit);
|
SharedPtr<ResourceLimit> resource_limit(new ResourceLimit(kernel));
|
||||||
|
|
||||||
resource_limit->name = std::move(name);
|
resource_limit->name = std::move(name);
|
||||||
return resource_limit;
|
return resource_limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory category) {
|
SharedPtr<ResourceLimit> ResourceLimitList::GetForCategory(ResourceLimitCategory category) {
|
||||||
switch (category) {
|
switch (category) {
|
||||||
case ResourceLimitCategory::APPLICATION:
|
case ResourceLimitCategory::APPLICATION:
|
||||||
case ResourceLimitCategory::SYS_APPLET:
|
case ResourceLimitCategory::SYS_APPLET:
|
||||||
|
@ -90,10 +88,10 @@ u32 ResourceLimit::GetMaxResourceValue(u32 resource) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceLimitsInit() {
|
ResourceLimitList::ResourceLimitList(KernelSystem& kernel) {
|
||||||
// Create the four resource limits that the system uses
|
// Create the four resource limits that the system uses
|
||||||
// Create the APPLICATION resource limit
|
// Create the APPLICATION resource limit
|
||||||
SharedPtr<ResourceLimit> resource_limit = ResourceLimit::Create("Applications");
|
SharedPtr<ResourceLimit> resource_limit = ResourceLimit::Create(kernel, "Applications");
|
||||||
resource_limit->max_priority = 0x18;
|
resource_limit->max_priority = 0x18;
|
||||||
resource_limit->max_commit = 0x4000000;
|
resource_limit->max_commit = 0x4000000;
|
||||||
resource_limit->max_threads = 0x20;
|
resource_limit->max_threads = 0x20;
|
||||||
|
@ -107,7 +105,7 @@ void ResourceLimitsInit() {
|
||||||
resource_limits[static_cast<u8>(ResourceLimitCategory::APPLICATION)] = resource_limit;
|
resource_limits[static_cast<u8>(ResourceLimitCategory::APPLICATION)] = resource_limit;
|
||||||
|
|
||||||
// Create the SYS_APPLET resource limit
|
// Create the SYS_APPLET resource limit
|
||||||
resource_limit = ResourceLimit::Create("System Applets");
|
resource_limit = ResourceLimit::Create(kernel, "System Applets");
|
||||||
resource_limit->max_priority = 0x4;
|
resource_limit->max_priority = 0x4;
|
||||||
resource_limit->max_commit = 0x5E00000;
|
resource_limit->max_commit = 0x5E00000;
|
||||||
resource_limit->max_threads = 0x1D;
|
resource_limit->max_threads = 0x1D;
|
||||||
|
@ -121,7 +119,7 @@ void ResourceLimitsInit() {
|
||||||
resource_limits[static_cast<u8>(ResourceLimitCategory::SYS_APPLET)] = resource_limit;
|
resource_limits[static_cast<u8>(ResourceLimitCategory::SYS_APPLET)] = resource_limit;
|
||||||
|
|
||||||
// Create the LIB_APPLET resource limit
|
// Create the LIB_APPLET resource limit
|
||||||
resource_limit = ResourceLimit::Create("Library Applets");
|
resource_limit = ResourceLimit::Create(kernel, "Library Applets");
|
||||||
resource_limit->max_priority = 0x4;
|
resource_limit->max_priority = 0x4;
|
||||||
resource_limit->max_commit = 0x600000;
|
resource_limit->max_commit = 0x600000;
|
||||||
resource_limit->max_threads = 0xE;
|
resource_limit->max_threads = 0xE;
|
||||||
|
@ -135,7 +133,7 @@ void ResourceLimitsInit() {
|
||||||
resource_limits[static_cast<u8>(ResourceLimitCategory::LIB_APPLET)] = resource_limit;
|
resource_limits[static_cast<u8>(ResourceLimitCategory::LIB_APPLET)] = resource_limit;
|
||||||
|
|
||||||
// Create the OTHER resource limit
|
// Create the OTHER resource limit
|
||||||
resource_limit = ResourceLimit::Create("Others");
|
resource_limit = ResourceLimit::Create(kernel, "Others");
|
||||||
resource_limit->max_priority = 0x4;
|
resource_limit->max_priority = 0x4;
|
||||||
resource_limit->max_commit = 0x2180000;
|
resource_limit->max_commit = 0x2180000;
|
||||||
resource_limit->max_threads = 0xE1;
|
resource_limit->max_threads = 0xE1;
|
||||||
|
@ -149,6 +147,6 @@ void ResourceLimitsInit() {
|
||||||
resource_limits[static_cast<u8>(ResourceLimitCategory::OTHER)] = resource_limit;
|
resource_limits[static_cast<u8>(ResourceLimitCategory::OTHER)] = resource_limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceLimitsShutdown() {}
|
ResourceLimitList::~ResourceLimitList() = default;
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/kernel/object.h"
|
#include "core/hle/kernel/object.h"
|
||||||
|
|
||||||
|
@ -34,14 +35,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Creates a resource limit object.
|
* Creates a resource limit object.
|
||||||
*/
|
*/
|
||||||
static SharedPtr<ResourceLimit> Create(std::string name = "Unknown");
|
static SharedPtr<ResourceLimit> Create(KernelSystem& kernel, std::string name = "Unknown");
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the resource limit associated with the specified resource limit category.
|
|
||||||
* @param category The resource limit category
|
|
||||||
* @returns The resource limit associated with the category
|
|
||||||
*/
|
|
||||||
static SharedPtr<ResourceLimit> GetForCategory(ResourceLimitCategory category);
|
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "ResourceLimit";
|
return "ResourceLimit";
|
||||||
|
@ -113,14 +107,24 @@ public:
|
||||||
s32 current_cpu_time = 0;
|
s32 current_cpu_time = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ResourceLimit();
|
explicit ResourceLimit(KernelSystem& kernel);
|
||||||
~ResourceLimit() override;
|
~ResourceLimit() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Initializes the resource limits
|
class ResourceLimitList {
|
||||||
void ResourceLimitsInit();
|
public:
|
||||||
|
explicit ResourceLimitList(KernelSystem& kernel);
|
||||||
|
~ResourceLimitList();
|
||||||
|
|
||||||
// Destroys the resource limits
|
/**
|
||||||
void ResourceLimitsShutdown();
|
* Retrieves the resource limit associated with the specified resource limit category.
|
||||||
|
* @param category The resource limit category
|
||||||
|
* @returns The resource limit associated with the category
|
||||||
|
*/
|
||||||
|
SharedPtr<ResourceLimit> GetForCategory(ResourceLimitCategory category);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::array<SharedPtr<ResourceLimit>, 4> resource_limits;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -10,16 +10,16 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
Semaphore::Semaphore() {}
|
Semaphore::Semaphore(KernelSystem& kernel) : WaitObject(kernel) {}
|
||||||
Semaphore::~Semaphore() {}
|
Semaphore::~Semaphore() {}
|
||||||
|
|
||||||
ResultVal<SharedPtr<Semaphore>> Semaphore::Create(s32 initial_count, s32 max_count,
|
ResultVal<SharedPtr<Semaphore>> KernelSystem::CreateSemaphore(s32 initial_count, s32 max_count,
|
||||||
std::string name) {
|
std::string name) {
|
||||||
|
|
||||||
if (initial_count > max_count)
|
if (initial_count > max_count)
|
||||||
return ERR_INVALID_COMBINATION_KERNEL;
|
return ERR_INVALID_COMBINATION_KERNEL;
|
||||||
|
|
||||||
SharedPtr<Semaphore> semaphore(new Semaphore);
|
SharedPtr<Semaphore> semaphore(new Semaphore(*this));
|
||||||
|
|
||||||
// When the semaphore is created, some slots are reserved for other threads,
|
// When the semaphore is created, some slots are reserved for other threads,
|
||||||
// and the rest is reserved for the caller thread
|
// and the rest is reserved for the caller thread
|
||||||
|
|
|
@ -15,16 +15,6 @@ namespace Kernel {
|
||||||
|
|
||||||
class Semaphore final : public WaitObject {
|
class Semaphore final : public WaitObject {
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* Creates a semaphore.
|
|
||||||
* @param initial_count Number of slots reserved for other threads
|
|
||||||
* @param max_count Maximum number of slots the semaphore can have
|
|
||||||
* @param name Optional name of semaphore
|
|
||||||
* @return The created semaphore
|
|
||||||
*/
|
|
||||||
static ResultVal<SharedPtr<Semaphore>> Create(s32 initial_count, s32 max_count,
|
|
||||||
std::string name = "Unknown");
|
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "Semaphore";
|
return "Semaphore";
|
||||||
}
|
}
|
||||||
|
@ -52,8 +42,10 @@ public:
|
||||||
ResultVal<s32> Release(s32 release_count);
|
ResultVal<s32> Release(s32 release_count);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Semaphore();
|
explicit Semaphore(KernelSystem& kernel);
|
||||||
~Semaphore() override;
|
~Semaphore() override;
|
||||||
|
|
||||||
|
friend class KernelSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
ServerPort::ServerPort() {}
|
ServerPort::ServerPort(KernelSystem& kernel) : WaitObject(kernel) {}
|
||||||
ServerPort::~ServerPort() {}
|
ServerPort::~ServerPort() {}
|
||||||
|
|
||||||
ResultVal<SharedPtr<ServerSession>> ServerPort::Accept() {
|
ResultVal<SharedPtr<ServerSession>> ServerPort::Accept() {
|
||||||
|
@ -35,11 +35,11 @@ void ServerPort::Acquire(Thread* thread) {
|
||||||
ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
|
ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortPair(
|
std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> KernelSystem::CreatePortPair(
|
||||||
u32 max_sessions, std::string name) {
|
u32 max_sessions, std::string name) {
|
||||||
|
|
||||||
SharedPtr<ServerPort> server_port(new ServerPort);
|
SharedPtr<ServerPort> server_port(new ServerPort(*this));
|
||||||
SharedPtr<ClientPort> client_port(new ClientPort);
|
SharedPtr<ClientPort> client_port(new ClientPort(*this));
|
||||||
|
|
||||||
server_port->name = name + "_Server";
|
server_port->name = name + "_Server";
|
||||||
client_port->name = name + "_Client";
|
client_port->name = name + "_Client";
|
||||||
|
|
|
@ -20,16 +20,6 @@ class SessionRequestHandler;
|
||||||
|
|
||||||
class ServerPort final : public WaitObject {
|
class ServerPort final : public WaitObject {
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* Creates a pair of ServerPort and an associated ClientPort.
|
|
||||||
*
|
|
||||||
* @param max_sessions Maximum number of sessions to the port
|
|
||||||
* @param name Optional name of the ports
|
|
||||||
* @return The created port tuple
|
|
||||||
*/
|
|
||||||
static std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> CreatePortPair(
|
|
||||||
u32 max_sessions, std::string name = "UnknownPort");
|
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "ServerPort";
|
return "ServerPort";
|
||||||
}
|
}
|
||||||
|
@ -69,8 +59,10 @@ public:
|
||||||
void Acquire(Thread* thread) override;
|
void Acquire(Thread* thread) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ServerPort();
|
explicit ServerPort(KernelSystem& kernel);
|
||||||
~ServerPort() override;
|
~ServerPort() override;
|
||||||
|
|
||||||
|
friend class KernelSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
ServerSession::ServerSession() = default;
|
ServerSession::ServerSession(KernelSystem& kernel) : WaitObject(kernel) {}
|
||||||
ServerSession::~ServerSession() {
|
ServerSession::~ServerSession() {
|
||||||
// This destructor will be called automatically when the last ServerSession handle is closed by
|
// This destructor will be called automatically when the last ServerSession handle is closed by
|
||||||
// the emulated application.
|
// the emulated application.
|
||||||
|
@ -28,8 +28,8 @@ ServerSession::~ServerSession() {
|
||||||
parent->server = nullptr;
|
parent->server = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<SharedPtr<ServerSession>> ServerSession::Create(std::string name) {
|
ResultVal<SharedPtr<ServerSession>> ServerSession::Create(KernelSystem& kernel, std::string name) {
|
||||||
SharedPtr<ServerSession> server_session(new ServerSession);
|
SharedPtr<ServerSession> server_session(new ServerSession(kernel));
|
||||||
|
|
||||||
server_session->name = std::move(name);
|
server_session->name = std::move(name);
|
||||||
server_session->parent = nullptr;
|
server_session->parent = nullptr;
|
||||||
|
@ -100,10 +100,10 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& name,
|
std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>> KernelSystem::CreateSessionPair(
|
||||||
SharedPtr<ClientPort> port) {
|
const std::string& name, SharedPtr<ClientPort> port) {
|
||||||
auto server_session = ServerSession::Create(name + "_Server").Unwrap();
|
auto server_session = ServerSession::Create(*this, name + "_Server").Unwrap();
|
||||||
SharedPtr<ClientSession> client_session(new ClientSession);
|
SharedPtr<ClientSession> client_session(new ClientSession(*this));
|
||||||
client_session->name = name + "_Client";
|
client_session->name = name + "_Client";
|
||||||
|
|
||||||
std::shared_ptr<Session> parent(new Session);
|
std::shared_ptr<Session> parent(new Session);
|
||||||
|
|
|
@ -48,17 +48,6 @@ public:
|
||||||
return HANDLE_TYPE;
|
return HANDLE_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
using SessionPair = std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a pair of ServerSession and an associated ClientSession.
|
|
||||||
* @param name Optional name of the ports.
|
|
||||||
* @param client_port Optional The ClientPort that spawned this session.
|
|
||||||
* @return The created session tuple
|
|
||||||
*/
|
|
||||||
static SessionPair CreateSessionPair(const std::string& name = "Unknown",
|
|
||||||
SharedPtr<ClientPort> client_port = nullptr);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the HLE handler for the session. This handler will be called to service IPC requests
|
* Sets the HLE handler for the session. This handler will be called to service IPC requests
|
||||||
* instead of the regular IPC machinery. (The regular IPC machinery is currently not
|
* instead of the regular IPC machinery. (The regular IPC machinery is currently not
|
||||||
|
@ -95,16 +84,20 @@ public:
|
||||||
SharedPtr<Thread> currently_handling;
|
SharedPtr<Thread> currently_handling;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ServerSession();
|
explicit ServerSession(KernelSystem& kernel);
|
||||||
~ServerSession() override;
|
~ServerSession() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a server session. The server session can have an optional HLE handler,
|
* Creates a server session. The server session can have an optional HLE handler,
|
||||||
* which will be invoked to handle the IPC requests that this session receives.
|
* which will be invoked to handle the IPC requests that this session receives.
|
||||||
|
* @param kernel The kernel instance to create the server session on
|
||||||
* @param name Optional name of the server session.
|
* @param name Optional name of the server session.
|
||||||
* @return The created server session
|
* @return The created server session
|
||||||
*/
|
*/
|
||||||
static ResultVal<SharedPtr<ServerSession>> Create(std::string name = "Unknown");
|
static ResultVal<SharedPtr<ServerSession>> Create(KernelSystem& kernel,
|
||||||
|
std::string name = "Unknown");
|
||||||
|
|
||||||
|
friend class KernelSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -11,14 +11,15 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
SharedMemory::SharedMemory() {}
|
SharedMemory::SharedMemory(KernelSystem& kernel) : Object(kernel) {}
|
||||||
SharedMemory::~SharedMemory() {}
|
SharedMemory::~SharedMemory() {}
|
||||||
|
|
||||||
SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u32 size,
|
SharedPtr<SharedMemory> KernelSystem::CreateSharedMemory(SharedPtr<Process> owner_process, u32 size,
|
||||||
MemoryPermission permissions,
|
MemoryPermission permissions,
|
||||||
MemoryPermission other_permissions, VAddr address,
|
MemoryPermission other_permissions,
|
||||||
MemoryRegion region, std::string name) {
|
VAddr address, MemoryRegion region,
|
||||||
SharedPtr<SharedMemory> shared_memory(new SharedMemory);
|
std::string name) {
|
||||||
|
SharedPtr<SharedMemory> shared_memory(new SharedMemory(*this));
|
||||||
|
|
||||||
shared_memory->owner_process = owner_process;
|
shared_memory->owner_process = owner_process;
|
||||||
shared_memory->name = std::move(name);
|
shared_memory->name = std::move(name);
|
||||||
|
@ -74,12 +75,10 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
|
||||||
return shared_memory;
|
return shared_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<SharedMemory> SharedMemory::CreateForApplet(std::shared_ptr<std::vector<u8>> heap_block,
|
SharedPtr<SharedMemory> KernelSystem::CreateSharedMemoryForApplet(
|
||||||
u32 offset, u32 size,
|
std::shared_ptr<std::vector<u8>> heap_block, u32 offset, u32 size, MemoryPermission permissions,
|
||||||
MemoryPermission permissions,
|
MemoryPermission other_permissions, std::string name) {
|
||||||
MemoryPermission other_permissions,
|
SharedPtr<SharedMemory> shared_memory(new SharedMemory(*this));
|
||||||
std::string name) {
|
|
||||||
SharedPtr<SharedMemory> shared_memory(new SharedMemory);
|
|
||||||
|
|
||||||
shared_memory->owner_process = nullptr;
|
shared_memory->owner_process = nullptr;
|
||||||
shared_memory->name = std::move(name);
|
shared_memory->name = std::move(name);
|
||||||
|
|
|
@ -12,55 +12,8 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
/// Permissions for mapped shared memory blocks
|
|
||||||
enum class MemoryPermission : u32 {
|
|
||||||
None = 0,
|
|
||||||
Read = (1u << 0),
|
|
||||||
Write = (1u << 1),
|
|
||||||
ReadWrite = (Read | Write),
|
|
||||||
Execute = (1u << 2),
|
|
||||||
ReadExecute = (Read | Execute),
|
|
||||||
WriteExecute = (Write | Execute),
|
|
||||||
ReadWriteExecute = (Read | Write | Execute),
|
|
||||||
DontCare = (1u << 28)
|
|
||||||
};
|
|
||||||
|
|
||||||
class SharedMemory final : public Object {
|
class SharedMemory final : public Object {
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* Creates a shared memory object.
|
|
||||||
* @param owner_process Process that created this shared memory object.
|
|
||||||
* @param size Size of the memory block. Must be page-aligned.
|
|
||||||
* @param permissions Permission restrictions applied to the process which created the block.
|
|
||||||
* @param other_permissions Permission restrictions applied to other processes mapping the
|
|
||||||
* block.
|
|
||||||
* @param address The address from which to map the Shared Memory.
|
|
||||||
* @param region If the address is 0, the shared memory will be allocated in this region of the
|
|
||||||
* linear heap.
|
|
||||||
* @param name Optional object name, used for debugging purposes.
|
|
||||||
*/
|
|
||||||
static SharedPtr<SharedMemory> Create(SharedPtr<Process> owner_process, u32 size,
|
|
||||||
MemoryPermission permissions,
|
|
||||||
MemoryPermission other_permissions, VAddr address = 0,
|
|
||||||
MemoryRegion region = MemoryRegion::BASE,
|
|
||||||
std::string name = "Unknown");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a shared memory object from a block of memory managed by an HLE applet.
|
|
||||||
* @param heap_block Heap block of the HLE applet.
|
|
||||||
* @param offset The offset into the heap block that the SharedMemory will map.
|
|
||||||
* @param size Size of the memory block. Must be page-aligned.
|
|
||||||
* @param permissions Permission restrictions applied to the process which created the block.
|
|
||||||
* @param other_permissions Permission restrictions applied to other processes mapping the
|
|
||||||
* block.
|
|
||||||
* @param name Optional object name, used for debugging purposes.
|
|
||||||
*/
|
|
||||||
static SharedPtr<SharedMemory> CreateForApplet(std::shared_ptr<std::vector<u8>> heap_block,
|
|
||||||
u32 offset, u32 size,
|
|
||||||
MemoryPermission permissions,
|
|
||||||
MemoryPermission other_permissions,
|
|
||||||
std::string name = "Unknown Applet");
|
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "SharedMemory";
|
return "SharedMemory";
|
||||||
}
|
}
|
||||||
|
@ -125,8 +78,10 @@ public:
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SharedMemory();
|
explicit SharedMemory(KernelSystem& kernel);
|
||||||
~SharedMemory() override;
|
~SharedMemory() override;
|
||||||
|
|
||||||
|
friend class KernelSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -615,7 +615,7 @@ static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_
|
||||||
|
|
||||||
/// Create an address arbiter (to allocate access to shared resources)
|
/// Create an address arbiter (to allocate access to shared resources)
|
||||||
static ResultCode CreateAddressArbiter(Handle* out_handle) {
|
static ResultCode CreateAddressArbiter(Handle* out_handle) {
|
||||||
SharedPtr<AddressArbiter> arbiter = AddressArbiter::Create();
|
SharedPtr<AddressArbiter> arbiter = Core::System::GetInstance().Kernel().CreateAddressArbiter();
|
||||||
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(arbiter)));
|
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(arbiter)));
|
||||||
LOG_TRACE(Kernel_SVC, "returned handle=0x{:08X}", *out_handle);
|
LOG_TRACE(Kernel_SVC, "returned handle=0x{:08X}", *out_handle);
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
|
@ -761,9 +761,9 @@ static ResultCode CreateThread(Handle* out_handle, u32 priority, u32 entry_point
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
CASCADE_RESULT(SharedPtr<Thread> thread,
|
CASCADE_RESULT(SharedPtr<Thread> thread, Core::System::GetInstance().Kernel().CreateThread(
|
||||||
Thread::Create(name, entry_point, priority, arg, processor_id, stack_top,
|
name, entry_point, priority, arg, processor_id,
|
||||||
g_current_process));
|
stack_top, g_current_process));
|
||||||
|
|
||||||
thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO |
|
thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO |
|
||||||
FPSCR_ROUND_TOZERO); // 0x03C00000
|
FPSCR_ROUND_TOZERO); // 0x03C00000
|
||||||
|
@ -828,7 +828,7 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
|
||||||
|
|
||||||
/// Create a mutex
|
/// Create a mutex
|
||||||
static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) {
|
static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) {
|
||||||
SharedPtr<Mutex> mutex = Mutex::Create(initial_locked != 0);
|
SharedPtr<Mutex> mutex = Core::System::GetInstance().Kernel().CreateMutex(initial_locked != 0);
|
||||||
mutex->name = fmt::format("mutex-{:08x}", Core::CPU().GetReg(14));
|
mutex->name = fmt::format("mutex-{:08x}", Core::CPU().GetReg(14));
|
||||||
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(mutex)));
|
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(mutex)));
|
||||||
|
|
||||||
|
@ -891,7 +891,8 @@ static ResultCode GetThreadId(u32* thread_id, Handle handle) {
|
||||||
|
|
||||||
/// Creates a semaphore
|
/// Creates a semaphore
|
||||||
static ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max_count) {
|
static ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max_count) {
|
||||||
CASCADE_RESULT(SharedPtr<Semaphore> semaphore, Semaphore::Create(initial_count, max_count));
|
CASCADE_RESULT(SharedPtr<Semaphore> semaphore,
|
||||||
|
Core::System::GetInstance().Kernel().CreateSemaphore(initial_count, max_count));
|
||||||
semaphore->name = fmt::format("semaphore-{:08x}", Core::CPU().GetReg(14));
|
semaphore->name = fmt::format("semaphore-{:08x}", Core::CPU().GetReg(14));
|
||||||
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(semaphore)));
|
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(semaphore)));
|
||||||
|
|
||||||
|
@ -942,8 +943,8 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, u32
|
||||||
|
|
||||||
/// Create an event
|
/// Create an event
|
||||||
static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) {
|
static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) {
|
||||||
SharedPtr<Event> evt = Event::Create(static_cast<ResetType>(reset_type),
|
SharedPtr<Event> evt = Core::System::GetInstance().Kernel().CreateEvent(
|
||||||
fmt::format("event-{:08x}", Core::CPU().GetReg(14)));
|
static_cast<ResetType>(reset_type), fmt::format("event-{:08x}", Core::CPU().GetReg(14)));
|
||||||
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(evt)));
|
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(evt)));
|
||||||
|
|
||||||
LOG_TRACE(Kernel_SVC, "called reset_type=0x{:08X} : created handle=0x{:08X}", reset_type,
|
LOG_TRACE(Kernel_SVC, "called reset_type=0x{:08X} : created handle=0x{:08X}", reset_type,
|
||||||
|
@ -985,8 +986,8 @@ static ResultCode ClearEvent(Handle handle) {
|
||||||
|
|
||||||
/// Creates a timer
|
/// Creates a timer
|
||||||
static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) {
|
static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) {
|
||||||
SharedPtr<Timer> timer = Timer::Create(static_cast<ResetType>(reset_type),
|
SharedPtr<Timer> timer = Core::System::GetInstance().Kernel().CreateTimer(
|
||||||
fmt ::format("timer-{:08x}", Core::CPU().GetReg(14)));
|
static_cast<ResetType>(reset_type), fmt ::format("timer-{:08x}", Core::CPU().GetReg(14)));
|
||||||
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(timer)));
|
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(timer)));
|
||||||
|
|
||||||
LOG_TRACE(Kernel_SVC, "called reset_type=0x{:08X} : created handle=0x{:08X}", reset_type,
|
LOG_TRACE(Kernel_SVC, "called reset_type=0x{:08X} : created handle=0x{:08X}", reset_type,
|
||||||
|
@ -1104,8 +1105,8 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32
|
||||||
if (addr == 0 && g_current_process->flags.shared_device_mem)
|
if (addr == 0 && g_current_process->flags.shared_device_mem)
|
||||||
region = g_current_process->flags.memory_region;
|
region = g_current_process->flags.memory_region;
|
||||||
|
|
||||||
shared_memory =
|
shared_memory = Core::System::GetInstance().Kernel().CreateSharedMemory(
|
||||||
SharedMemory::Create(g_current_process, size, static_cast<MemoryPermission>(my_permission),
|
g_current_process, size, static_cast<MemoryPermission>(my_permission),
|
||||||
static_cast<MemoryPermission>(other_permission), addr, region);
|
static_cast<MemoryPermission>(other_permission), addr, region);
|
||||||
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(shared_memory)));
|
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(shared_memory)));
|
||||||
|
|
||||||
|
@ -1118,7 +1119,7 @@ static ResultCode CreatePort(Handle* server_port, Handle* client_port, VAddr nam
|
||||||
// TODO(Subv): Implement named ports.
|
// TODO(Subv): Implement named ports.
|
||||||
ASSERT_MSG(name_address == 0, "Named ports are currently unimplemented");
|
ASSERT_MSG(name_address == 0, "Named ports are currently unimplemented");
|
||||||
|
|
||||||
auto ports = ServerPort::CreatePortPair(max_sessions);
|
auto ports = Core::System::GetInstance().Kernel().CreatePortPair(max_sessions);
|
||||||
CASCADE_RESULT(*client_port,
|
CASCADE_RESULT(*client_port,
|
||||||
g_handle_table.Create(std::move(std::get<SharedPtr<ClientPort>>(ports))));
|
g_handle_table.Create(std::move(std::get<SharedPtr<ClientPort>>(ports))));
|
||||||
// Note: The 3DS kernel also leaks the client port handle if the server port handle fails to be
|
// Note: The 3DS kernel also leaks the client port handle if the server port handle fails to be
|
||||||
|
@ -1141,7 +1142,7 @@ static ResultCode CreateSessionToPort(Handle* out_client_session, Handle client_
|
||||||
}
|
}
|
||||||
|
|
||||||
static ResultCode CreateSession(Handle* server_session, Handle* client_session) {
|
static ResultCode CreateSession(Handle* server_session, Handle* client_session) {
|
||||||
auto sessions = ServerSession::CreateSessionPair();
|
auto sessions = Core::System::GetInstance().Kernel().CreateSessionPair();
|
||||||
|
|
||||||
auto& server = std::get<SharedPtr<ServerSession>>(sessions);
|
auto& server = std::get<SharedPtr<ServerSession>>(sessions);
|
||||||
CASCADE_RESULT(*server_session, g_handle_table.Create(std::move(server)));
|
CASCADE_RESULT(*server_session, g_handle_table.Create(std::move(server)));
|
||||||
|
|
|
@ -60,7 +60,7 @@ inline static u32 const NewThreadId() {
|
||||||
return next_thread_id++;
|
return next_thread_id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::Thread() : context(Core::CPU().NewContext()) {}
|
Thread::Thread(KernelSystem& kernel) : WaitObject(kernel), context(Core::CPU().NewContext()) {}
|
||||||
Thread::~Thread() {}
|
Thread::~Thread() {}
|
||||||
|
|
||||||
Thread* GetCurrentThread() {
|
Thread* GetCurrentThread() {
|
||||||
|
@ -320,8 +320,9 @@ static void ResetThreadContext(const std::unique_ptr<ARM_Interface::ThreadContex
|
||||||
context->SetCpsr(USER32MODE | ((entry_point & 1) << 5)); // Usermode and THUMB mode
|
context->SetCpsr(USER32MODE | ((entry_point & 1) << 5)); // Usermode and THUMB mode
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, u32 priority,
|
ResultVal<SharedPtr<Thread>> KernelSystem::CreateThread(std::string name, VAddr entry_point,
|
||||||
u32 arg, s32 processor_id, VAddr stack_top,
|
u32 priority, u32 arg, s32 processor_id,
|
||||||
|
VAddr stack_top,
|
||||||
SharedPtr<Process> owner_process) {
|
SharedPtr<Process> owner_process) {
|
||||||
// Check if priority is in ranged. Lowest priority -> highest priority id.
|
// Check if priority is in ranged. Lowest priority -> highest priority id.
|
||||||
if (priority > ThreadPrioLowest) {
|
if (priority > ThreadPrioLowest) {
|
||||||
|
@ -343,7 +344,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
|
||||||
ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
|
ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<Thread> thread(new Thread);
|
SharedPtr<Thread> thread(new Thread(*this));
|
||||||
|
|
||||||
thread_list.push_back(thread);
|
thread_list.push_back(thread);
|
||||||
ready_queue.prepare(priority);
|
ready_queue.prepare(priority);
|
||||||
|
@ -443,10 +444,11 @@ void Thread::BoostPriority(u32 priority) {
|
||||||
current_priority = priority;
|
current_priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<Thread> SetupMainThread(u32 entry_point, u32 priority, SharedPtr<Process> owner_process) {
|
SharedPtr<Thread> SetupMainThread(KernelSystem& kernel, u32 entry_point, u32 priority,
|
||||||
|
SharedPtr<Process> owner_process) {
|
||||||
// Initialize new "main" thread
|
// Initialize new "main" thread
|
||||||
auto thread_res =
|
auto thread_res =
|
||||||
Thread::Create("main", entry_point, priority, 0, owner_process->ideal_processor,
|
kernel.CreateThread("main", entry_point, priority, 0, owner_process->ideal_processor,
|
||||||
Memory::HEAP_VADDR_END, owner_process);
|
Memory::HEAP_VADDR_END, owner_process);
|
||||||
|
|
||||||
SharedPtr<Thread> thread = std::move(thread_res).Unwrap();
|
SharedPtr<Thread> thread = std::move(thread_res).Unwrap();
|
||||||
|
|
|
@ -55,21 +55,6 @@ enum class ThreadWakeupReason {
|
||||||
|
|
||||||
class Thread final : public WaitObject {
|
class Thread final : public WaitObject {
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* Creates and returns a new thread. The new thread is immediately scheduled
|
|
||||||
* @param name The friendly name desired for the thread
|
|
||||||
* @param entry_point The address at which the thread should start execution
|
|
||||||
* @param priority The thread's priority
|
|
||||||
* @param arg User data to pass to the thread
|
|
||||||
* @param processor_id The ID(s) of the processors on which the thread is desired to be run
|
|
||||||
* @param stack_top The address of the thread's stack top
|
|
||||||
* @param owner_process The parent process for the thread
|
|
||||||
* @return A shared pointer to the newly created thread
|
|
||||||
*/
|
|
||||||
static ResultVal<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, u32 priority,
|
|
||||||
u32 arg, s32 processor_id, VAddr stack_top,
|
|
||||||
SharedPtr<Process> owner_process);
|
|
||||||
|
|
||||||
std::string GetName() const override {
|
std::string GetName() const override {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -225,18 +210,22 @@ public:
|
||||||
std::function<WakeupCallback> wakeup_callback;
|
std::function<WakeupCallback> wakeup_callback;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Thread();
|
explicit Thread(KernelSystem&);
|
||||||
~Thread() override;
|
~Thread() override;
|
||||||
|
|
||||||
|
friend class KernelSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up the primary application thread
|
* Sets up the primary application thread
|
||||||
|
* @param kernel The kernel instance on which the thread is created
|
||||||
* @param entry_point The address at which the thread should start execution
|
* @param entry_point The address at which the thread should start execution
|
||||||
* @param priority The priority to give the main thread
|
* @param priority The priority to give the main thread
|
||||||
* @param owner_process The parent process for the main thread
|
* @param owner_process The parent process for the main thread
|
||||||
* @return A shared pointer to the main thread
|
* @return A shared pointer to the main thread
|
||||||
*/
|
*/
|
||||||
SharedPtr<Thread> SetupMainThread(u32 entry_point, u32 priority, SharedPtr<Process> owner_process);
|
SharedPtr<Thread> SetupMainThread(KernelSystem& kernel, u32 entry_point, u32 priority,
|
||||||
|
SharedPtr<Process> owner_process);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether there are any threads that are ready to run.
|
* Returns whether there are any threads that are ready to run.
|
||||||
|
|
|
@ -19,11 +19,11 @@ static CoreTiming::EventType* timer_callback_event_type = nullptr;
|
||||||
// us to simply use a pool index or similar.
|
// us to simply use a pool index or similar.
|
||||||
static Kernel::HandleTable timer_callback_handle_table;
|
static Kernel::HandleTable timer_callback_handle_table;
|
||||||
|
|
||||||
Timer::Timer() {}
|
Timer::Timer(KernelSystem& kernel) : WaitObject(kernel) {}
|
||||||
Timer::~Timer() {}
|
Timer::~Timer() {}
|
||||||
|
|
||||||
SharedPtr<Timer> Timer::Create(ResetType reset_type, std::string name) {
|
SharedPtr<Timer> KernelSystem::CreateTimer(ResetType reset_type, std::string name) {
|
||||||
SharedPtr<Timer> timer(new Timer);
|
SharedPtr<Timer> timer(new Timer(*this));
|
||||||
|
|
||||||
timer->reset_type = reset_type;
|
timer->reset_type = reset_type;
|
||||||
timer->signaled = false;
|
timer->signaled = false;
|
||||||
|
|
|
@ -12,14 +12,6 @@ namespace Kernel {
|
||||||
|
|
||||||
class Timer final : public WaitObject {
|
class Timer final : public WaitObject {
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* Creates a timer
|
|
||||||
* @param reset_type ResetType describing how to create the timer
|
|
||||||
* @param name Optional name of timer
|
|
||||||
* @return The created Timer
|
|
||||||
*/
|
|
||||||
static SharedPtr<Timer> Create(ResetType reset_type, std::string name = "Unknown");
|
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "Timer";
|
return "Timer";
|
||||||
}
|
}
|
||||||
|
@ -68,7 +60,7 @@ public:
|
||||||
void Signal(s64 cycles_late);
|
void Signal(s64 cycles_late);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Timer();
|
explicit Timer(KernelSystem& kernel);
|
||||||
~Timer() override;
|
~Timer() override;
|
||||||
|
|
||||||
ResetType reset_type; ///< The ResetType of this timer
|
ResetType reset_type; ///< The ResetType of this timer
|
||||||
|
@ -81,6 +73,8 @@ private:
|
||||||
|
|
||||||
/// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
|
/// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
|
||||||
Handle callback_handle;
|
Handle callback_handle;
|
||||||
|
|
||||||
|
friend class KernelSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Initializes the required variables for timers
|
/// Initializes the required variables for timers
|
||||||
|
|
|
@ -16,6 +16,8 @@ class Thread;
|
||||||
/// Class that represents a Kernel object that a thread can be waiting on
|
/// Class that represents a Kernel object that a thread can be waiting on
|
||||||
class WaitObject : public Object {
|
class WaitObject : public Object {
|
||||||
public:
|
public:
|
||||||
|
using Object::Object;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the specified thread should wait until the object is available
|
* Check if the specified thread should wait until the object is available
|
||||||
* @param thread The thread about which we're deciding.
|
* @param thread The thread about which we're deciding.
|
||||||
|
|
|
@ -1026,8 +1026,8 @@ void Module::Interface::BeginImportProgram(Kernel::HLERequestContext& ctx) {
|
||||||
// Create our CIAFile handle for the app to write to, and while the app writes
|
// Create our CIAFile handle for the app to write to, and while the app writes
|
||||||
// Citra will store contents out to sdmc/nand
|
// Citra will store contents out to sdmc/nand
|
||||||
const FileSys::Path cia_path = {};
|
const FileSys::Path cia_path = {};
|
||||||
auto file =
|
auto file = std::make_shared<Service::FS::File>(
|
||||||
std::make_shared<Service::FS::File>(std::make_unique<CIAFile>(media_type), cia_path);
|
am->system, std::make_unique<CIAFile>(media_type), cia_path);
|
||||||
|
|
||||||
am->cia_installing = true;
|
am->cia_installing = true;
|
||||||
|
|
||||||
|
@ -1053,8 +1053,8 @@ void Module::Interface::BeginImportProgramTemporarily(Kernel::HLERequestContext&
|
||||||
// Create our CIAFile handle for the app to write to, and while the app writes Citra will store
|
// Create our CIAFile handle for the app to write to, and while the app writes Citra will store
|
||||||
// contents out to sdmc/nand
|
// contents out to sdmc/nand
|
||||||
const FileSys::Path cia_path = {};
|
const FileSys::Path cia_path = {};
|
||||||
auto file = std::make_shared<Service::FS::File>(std::make_unique<CIAFile>(FS::MediaType::NAND),
|
auto file = std::make_shared<Service::FS::File>(
|
||||||
cia_path);
|
am->system, std::make_unique<CIAFile>(FS::MediaType::NAND), cia_path);
|
||||||
|
|
||||||
am->cia_installing = true;
|
am->cia_installing = true;
|
||||||
|
|
||||||
|
@ -1455,16 +1455,16 @@ void Module::Interface::GetMetaDataFromCia(Kernel::HLERequestContext& ctx) {
|
||||||
rb.PushMappedBuffer(output_buffer);
|
rb.PushMappedBuffer(output_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Module::Module() {
|
Module::Module(Core::System& system) : system(system) {
|
||||||
ScanForAllTitles();
|
ScanForAllTitles();
|
||||||
system_updater_mutex = Kernel::Mutex::Create(false, "AM::SystemUpdaterMutex");
|
system_updater_mutex = system.Kernel().CreateMutex(false, "AM::SystemUpdaterMutex");
|
||||||
}
|
}
|
||||||
|
|
||||||
Module::~Module() = default;
|
Module::~Module() = default;
|
||||||
|
|
||||||
void InstallInterfaces(Core::System& system) {
|
void InstallInterfaces(Core::System& system) {
|
||||||
auto& service_manager = system.ServiceManager();
|
auto& service_manager = system.ServiceManager();
|
||||||
auto am = std::make_shared<Module>();
|
auto am = std::make_shared<Module>(system);
|
||||||
std::make_shared<AM_APP>(am)->InstallAsService(service_manager);
|
std::make_shared<AM_APP>(am)->InstallAsService(service_manager);
|
||||||
std::make_shared<AM_NET>(am)->InstallAsService(service_manager);
|
std::make_shared<AM_NET>(am)->InstallAsService(service_manager);
|
||||||
std::make_shared<AM_SYS>(am)->InstallAsService(service_manager);
|
std::make_shared<AM_SYS>(am)->InstallAsService(service_manager);
|
||||||
|
|
|
@ -149,7 +149,7 @@ std::string GetMediaTitlePath(Service::FS::MediaType media_type);
|
||||||
|
|
||||||
class Module final {
|
class Module final {
|
||||||
public:
|
public:
|
||||||
Module();
|
explicit Module(Core::System& system);
|
||||||
~Module();
|
~Module();
|
||||||
|
|
||||||
class Interface : public ServiceFramework<Interface> {
|
class Interface : public ServiceFramework<Interface> {
|
||||||
|
@ -573,6 +573,7 @@ private:
|
||||||
*/
|
*/
|
||||||
void ScanForAllTitles();
|
void ScanForAllTitles();
|
||||||
|
|
||||||
|
Core::System& system;
|
||||||
bool cia_installing = false;
|
bool cia_installing = false;
|
||||||
std::array<std::vector<u64_le>, 3> am_title_list;
|
std::array<std::vector<u64_le>, 3> am_title_list;
|
||||||
Kernel::SharedPtr<Kernel::Mutex> system_updater_mutex;
|
Kernel::SharedPtr<Kernel::Mutex> system_updater_mutex;
|
||||||
|
|
|
@ -572,9 +572,9 @@ AppletManager::AppletManager(Core::System& system) : system(system) {
|
||||||
slot_data.registered = false;
|
slot_data.registered = false;
|
||||||
slot_data.loaded = false;
|
slot_data.loaded = false;
|
||||||
slot_data.notification_event =
|
slot_data.notification_event =
|
||||||
Kernel::Event::Create(Kernel::ResetType::OneShot, "APT:Notification");
|
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "APT:Notification");
|
||||||
slot_data.parameter_event =
|
slot_data.parameter_event =
|
||||||
Kernel::Event::Create(Kernel::ResetType::OneShot, "APT:Parameter");
|
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "APT:Parameter");
|
||||||
}
|
}
|
||||||
HLE::Applets::Init();
|
HLE::Applets::Init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -855,11 +855,11 @@ Module::Module(Core::System& system) : system(system) {
|
||||||
|
|
||||||
using Kernel::MemoryPermission;
|
using Kernel::MemoryPermission;
|
||||||
shared_font_mem =
|
shared_font_mem =
|
||||||
Kernel::SharedMemory::Create(nullptr, 0x332000, // 3272 KB
|
system.Kernel().CreateSharedMemory(nullptr, 0x332000, // 3272 KB
|
||||||
MemoryPermission::ReadWrite, MemoryPermission::Read, 0,
|
MemoryPermission::ReadWrite, MemoryPermission::Read, 0,
|
||||||
Kernel::MemoryRegion::SYSTEM, "APT:SharedFont");
|
Kernel::MemoryRegion::SYSTEM, "APT:SharedFont");
|
||||||
|
|
||||||
lock = Kernel::Mutex::Create(false, "APT_U:Lock");
|
lock = system.Kernel().CreateMutex(false, "APT_U:Lock");
|
||||||
}
|
}
|
||||||
|
|
||||||
Module::~Module() {}
|
Module::~Module() {}
|
||||||
|
|
|
@ -903,15 +903,16 @@ void Module::Interface::GetNsDataNewFlagPrivileged(Kernel::HLERequestContext& ct
|
||||||
Module::Interface::Interface(std::shared_ptr<Module> boss, const char* name, u32 max_session)
|
Module::Interface::Interface(std::shared_ptr<Module> boss, const char* name, u32 max_session)
|
||||||
: ServiceFramework(name, max_session), boss(std::move(boss)) {}
|
: ServiceFramework(name, max_session), boss(std::move(boss)) {}
|
||||||
|
|
||||||
Module::Module() {
|
Module::Module(Core::System& system) {
|
||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
// TODO: verify ResetType
|
// TODO: verify ResetType
|
||||||
task_finish_event = Event::Create(Kernel::ResetType::OneShot, "BOSS::task_finish_event");
|
task_finish_event =
|
||||||
|
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "BOSS::task_finish_event");
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstallInterfaces(Core::System& system) {
|
void InstallInterfaces(Core::System& system) {
|
||||||
auto& service_manager = system.ServiceManager();
|
auto& service_manager = system.ServiceManager();
|
||||||
auto boss = std::make_shared<Module>();
|
auto boss = std::make_shared<Module>(system);
|
||||||
std::make_shared<BOSS_P>(boss)->InstallAsService(service_manager);
|
std::make_shared<BOSS_P>(boss)->InstallAsService(service_manager);
|
||||||
std::make_shared<BOSS_U>(boss)->InstallAsService(service_manager);
|
std::make_shared<BOSS_U>(boss)->InstallAsService(service_manager);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace Service::BOSS {
|
||||||
|
|
||||||
class Module final {
|
class Module final {
|
||||||
public:
|
public:
|
||||||
Module();
|
explicit Module(Core::System& system);
|
||||||
~Module() = default;
|
~Module() = default;
|
||||||
|
|
||||||
class Interface : public ServiceFramework<Interface> {
|
class Interface : public ServiceFramework<Interface> {
|
||||||
|
|
|
@ -1019,14 +1019,15 @@ void Module::Interface::DriverFinalize(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_CAM, "called");
|
LOG_DEBUG(Service_CAM, "called");
|
||||||
}
|
}
|
||||||
|
|
||||||
Module::Module() {
|
Module::Module(Core::System& system) {
|
||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
for (PortConfig& port : ports) {
|
for (PortConfig& port : ports) {
|
||||||
port.completion_event = Event::Create(ResetType::Sticky, "CAM::completion_event");
|
port.completion_event =
|
||||||
|
system.Kernel().CreateEvent(ResetType::Sticky, "CAM::completion_event");
|
||||||
port.buffer_error_interrupt_event =
|
port.buffer_error_interrupt_event =
|
||||||
Event::Create(ResetType::OneShot, "CAM::buffer_error_interrupt_event");
|
system.Kernel().CreateEvent(ResetType::OneShot, "CAM::buffer_error_interrupt_event");
|
||||||
port.vsync_interrupt_event =
|
port.vsync_interrupt_event =
|
||||||
Event::Create(ResetType::OneShot, "CAM::vsync_interrupt_event");
|
system.Kernel().CreateEvent(ResetType::OneShot, "CAM::vsync_interrupt_event");
|
||||||
}
|
}
|
||||||
completion_event_callback = CoreTiming::RegisterEvent(
|
completion_event_callback = CoreTiming::RegisterEvent(
|
||||||
"CAM::CompletionEventCallBack",
|
"CAM::CompletionEventCallBack",
|
||||||
|
@ -1061,7 +1062,7 @@ std::shared_ptr<Module> GetModule(Core::System& system) {
|
||||||
|
|
||||||
void InstallInterfaces(Core::System& system) {
|
void InstallInterfaces(Core::System& system) {
|
||||||
auto& service_manager = system.ServiceManager();
|
auto& service_manager = system.ServiceManager();
|
||||||
auto cam = std::make_shared<Module>();
|
auto cam = std::make_shared<Module>(system);
|
||||||
|
|
||||||
std::make_shared<CAM_U>(cam)->InstallAsService(service_manager);
|
std::make_shared<CAM_U>(cam)->InstallAsService(service_manager);
|
||||||
std::make_shared<CAM_S>(cam)->InstallAsService(service_manager);
|
std::make_shared<CAM_S>(cam)->InstallAsService(service_manager);
|
||||||
|
|
|
@ -241,7 +241,7 @@ static_assert(sizeof(PackageParameterWithContextDetail) == 28,
|
||||||
|
|
||||||
class Module final {
|
class Module final {
|
||||||
public:
|
public:
|
||||||
Module();
|
explicit Module(Core::System& system);
|
||||||
~Module();
|
~Module();
|
||||||
void ReloadCameraDevices();
|
void ReloadCameraDevices();
|
||||||
|
|
||||||
|
|
|
@ -1351,10 +1351,11 @@ Module::SessionData::~SessionData() {
|
||||||
Module::Interface::Interface(std::shared_ptr<Module> cecd, const char* name, u32 max_session)
|
Module::Interface::Interface(std::shared_ptr<Module> cecd, const char* name, u32 max_session)
|
||||||
: ServiceFramework(name, max_session), cecd(std::move(cecd)) {}
|
: ServiceFramework(name, max_session), cecd(std::move(cecd)) {}
|
||||||
|
|
||||||
Module::Module() {
|
Module::Module(Core::System& system) {
|
||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
cecinfo_event = Event::Create(Kernel::ResetType::OneShot, "CECD::cecinfo_event");
|
cecinfo_event = system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "CECD::cecinfo_event");
|
||||||
change_state_event = Event::Create(Kernel::ResetType::OneShot, "CECD::change_state_event");
|
change_state_event =
|
||||||
|
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "CECD::change_state_event");
|
||||||
|
|
||||||
std::string nand_directory = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
|
std::string nand_directory = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
|
||||||
FileSys::ArchiveFactory_SystemSaveData systemsavedata_factory(nand_directory);
|
FileSys::ArchiveFactory_SystemSaveData systemsavedata_factory(nand_directory);
|
||||||
|
@ -1433,7 +1434,7 @@ Module::~Module() = default;
|
||||||
|
|
||||||
void InstallInterfaces(Core::System& system) {
|
void InstallInterfaces(Core::System& system) {
|
||||||
auto& service_manager = system.ServiceManager();
|
auto& service_manager = system.ServiceManager();
|
||||||
auto cecd = std::make_shared<Module>();
|
auto cecd = std::make_shared<Module>(system);
|
||||||
std::make_shared<CECD_NDM>(cecd)->InstallAsService(service_manager);
|
std::make_shared<CECD_NDM>(cecd)->InstallAsService(service_manager);
|
||||||
std::make_shared<CECD_S>(cecd)->InstallAsService(service_manager);
|
std::make_shared<CECD_S>(cecd)->InstallAsService(service_manager);
|
||||||
std::make_shared<CECD_U>(cecd)->InstallAsService(service_manager);
|
std::make_shared<CECD_U>(cecd)->InstallAsService(service_manager);
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace Service::CECD {
|
||||||
|
|
||||||
class Module final {
|
class Module final {
|
||||||
public:
|
public:
|
||||||
Module();
|
explicit Module(Core::System& system);
|
||||||
~Module();
|
~Module();
|
||||||
|
|
||||||
enum class CecCommand : u32 {
|
enum class CecCommand : u32 {
|
||||||
|
|
|
@ -19,9 +19,9 @@ void CSND_SND::Initialize(Kernel::HLERequestContext& ctx) {
|
||||||
const u32 offset3 = rp.Pop<u32>();
|
const u32 offset3 = rp.Pop<u32>();
|
||||||
|
|
||||||
using Kernel::MemoryPermission;
|
using Kernel::MemoryPermission;
|
||||||
mutex = Kernel::Mutex::Create(false, "CSND:mutex");
|
mutex = system.Kernel().CreateMutex(false, "CSND:mutex");
|
||||||
shared_memory = Kernel::SharedMemory::Create(nullptr, size, MemoryPermission::ReadWrite,
|
shared_memory = system.Kernel().CreateSharedMemory(
|
||||||
MemoryPermission::ReadWrite, 0,
|
nullptr, size, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, 0,
|
||||||
Kernel::MemoryRegion::BASE, "CSND:SharedMemory");
|
Kernel::MemoryRegion::BASE, "CSND:SharedMemory");
|
||||||
|
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 3);
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 3);
|
||||||
|
@ -173,7 +173,7 @@ void CSND_SND::Reset(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_WARNING(Service_CSND, "(STUBBED) called");
|
LOG_WARNING(Service_CSND, "(STUBBED) called");
|
||||||
}
|
}
|
||||||
|
|
||||||
CSND_SND::CSND_SND() : ServiceFramework("csnd:SND", 4) {
|
CSND_SND::CSND_SND(Core::System& system) : ServiceFramework("csnd:SND", 4), system(system) {
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
{0x00010140, &CSND_SND::Initialize, "Initialize"},
|
{0x00010140, &CSND_SND::Initialize, "Initialize"},
|
||||||
|
@ -196,7 +196,7 @@ CSND_SND::CSND_SND() : ServiceFramework("csnd:SND", 4) {
|
||||||
|
|
||||||
void InstallInterfaces(Core::System& system) {
|
void InstallInterfaces(Core::System& system) {
|
||||||
auto& service_manager = system.ServiceManager();
|
auto& service_manager = system.ServiceManager();
|
||||||
std::make_shared<CSND_SND>()->InstallAsService(service_manager);
|
std::make_shared<CSND_SND>(system)->InstallAsService(service_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::CSND
|
} // namespace Service::CSND
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace Service::CSND {
|
||||||
|
|
||||||
class CSND_SND final : public ServiceFramework<CSND_SND> {
|
class CSND_SND final : public ServiceFramework<CSND_SND> {
|
||||||
public:
|
public:
|
||||||
CSND_SND();
|
explicit CSND_SND(Core::System& system);
|
||||||
~CSND_SND() = default;
|
~CSND_SND() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -174,6 +174,8 @@ private:
|
||||||
};
|
};
|
||||||
static_assert(sizeof(Type0Command) == 0x20, "Type0Command structure size is wrong");
|
static_assert(sizeof(Type0Command) == 0x20, "Type0Command structure size is wrong");
|
||||||
|
|
||||||
|
Core::System& system;
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::Mutex> mutex = nullptr;
|
Kernel::SharedPtr<Kernel::Mutex> mutex = nullptr;
|
||||||
Kernel::SharedPtr<Kernel::SharedMemory> shared_memory = nullptr;
|
Kernel::SharedPtr<Kernel::SharedMemory> shared_memory = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -350,7 +350,7 @@ bool DSP_DSP::HasTooManyEventsRegistered() const {
|
||||||
return number >= max_number_of_interrupt_events;
|
return number >= max_number_of_interrupt_events;
|
||||||
}
|
}
|
||||||
|
|
||||||
DSP_DSP::DSP_DSP() : ServiceFramework("dsp::DSP", DefaultMaxSessions) {
|
DSP_DSP::DSP_DSP(Core::System& system) : ServiceFramework("dsp::DSP", DefaultMaxSessions) {
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
{0x00010040, &DSP_DSP::RecvData, "RecvData"},
|
{0x00010040, &DSP_DSP::RecvData, "RecvData"},
|
||||||
|
@ -391,7 +391,8 @@ DSP_DSP::DSP_DSP() : ServiceFramework("dsp::DSP", DefaultMaxSessions) {
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
|
|
||||||
semaphore_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "DSP_DSP::semaphore_event");
|
semaphore_event =
|
||||||
|
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "DSP_DSP::semaphore_event");
|
||||||
}
|
}
|
||||||
|
|
||||||
DSP_DSP::~DSP_DSP() {
|
DSP_DSP::~DSP_DSP() {
|
||||||
|
@ -401,7 +402,7 @@ DSP_DSP::~DSP_DSP() {
|
||||||
|
|
||||||
void InstallInterfaces(Core::System& system) {
|
void InstallInterfaces(Core::System& system) {
|
||||||
auto& service_manager = system.ServiceManager();
|
auto& service_manager = system.ServiceManager();
|
||||||
auto dsp = std::make_shared<DSP_DSP>();
|
auto dsp = std::make_shared<DSP_DSP>(system);
|
||||||
dsp->InstallAsService(service_manager);
|
dsp->InstallAsService(service_manager);
|
||||||
Core::DSP().SetServiceToInterrupt(std::move(dsp));
|
Core::DSP().SetServiceToInterrupt(std::move(dsp));
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace Service::DSP {
|
||||||
|
|
||||||
class DSP_DSP final : public ServiceFramework<DSP_DSP> {
|
class DSP_DSP final : public ServiceFramework<DSP_DSP> {
|
||||||
public:
|
public:
|
||||||
DSP_DSP();
|
explicit DSP_DSP(Core::System& system);
|
||||||
~DSP_DSP();
|
~DSP_DSP();
|
||||||
|
|
||||||
/// There are three types of interrupts
|
/// There are three types of interrupts
|
||||||
|
|
|
@ -244,7 +244,7 @@ ERR_F::~ERR_F() = default;
|
||||||
|
|
||||||
void InstallInterfaces(Core::System& system) {
|
void InstallInterfaces(Core::System& system) {
|
||||||
auto errf = std::make_shared<ERR_F>(system);
|
auto errf = std::make_shared<ERR_F>(system);
|
||||||
errf->InstallAsNamedPort();
|
errf->InstallAsNamedPort(system.Kernel());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::ERR
|
} // namespace Service::ERR
|
||||||
|
|
|
@ -87,7 +87,7 @@ ResultVal<std::shared_ptr<File>> ArchiveManager::OpenFileFromArchive(ArchiveHand
|
||||||
if (backend.Failed())
|
if (backend.Failed())
|
||||||
return backend.Code();
|
return backend.Code();
|
||||||
|
|
||||||
auto file = std::shared_ptr<File>(new File(std::move(backend).Unwrap(), path));
|
auto file = std::shared_ptr<File>(new File(system, std::move(backend).Unwrap(), path));
|
||||||
return MakeResult<std::shared_ptr<File>>(std::move(file));
|
return MakeResult<std::shared_ptr<File>>(std::move(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +348,7 @@ void ArchiveManager::RegisterSelfNCCH(Loader::AppLoader& app_loader) {
|
||||||
factory->Register(app_loader);
|
factory->Register(app_loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArchiveManager::ArchiveManager() {
|
ArchiveManager::ArchiveManager(Core::System& system) : system(system) {
|
||||||
RegisterArchiveTypes();
|
RegisterArchiveTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,10 @@ namespace Loader {
|
||||||
class AppLoader;
|
class AppLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Service::FS {
|
namespace Service::FS {
|
||||||
|
|
||||||
/// Supported archive types
|
/// Supported archive types
|
||||||
|
@ -50,7 +54,8 @@ using FileSys::ArchiveFactory;
|
||||||
|
|
||||||
class ArchiveManager {
|
class ArchiveManager {
|
||||||
public:
|
public:
|
||||||
ArchiveManager();
|
explicit ArchiveManager(Core::System& system);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens an archive
|
* Opens an archive
|
||||||
* @param id_code IdCode of the archive to open
|
* @param id_code IdCode of the archive to open
|
||||||
|
@ -224,6 +229,8 @@ public:
|
||||||
void RegisterSelfNCCH(Loader::AppLoader& app_loader);
|
void RegisterSelfNCCH(Loader::AppLoader& app_loader);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Core::System& system;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers an Archive type, instances of which can later be opened using its IdCode.
|
* Registers an Archive type, instances of which can later be opened using its IdCode.
|
||||||
* @param factory File system backend interface to the archive
|
* @param factory File system backend interface to the archive
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/file_sys/errors.h"
|
#include "core/file_sys/errors.h"
|
||||||
#include "core/file_sys/file_backend.h"
|
#include "core/file_sys/file_backend.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
|
@ -14,8 +15,9 @@
|
||||||
|
|
||||||
namespace Service::FS {
|
namespace Service::FS {
|
||||||
|
|
||||||
File::File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path)
|
File::File(Core::System& system, std::unique_ptr<FileSys::FileBackend>&& backend,
|
||||||
: ServiceFramework("", 1), path(path), backend(std::move(backend)) {
|
const FileSys::Path& path)
|
||||||
|
: ServiceFramework("", 1), path(path), backend(std::move(backend)), system(system) {
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0x08010100, &File::OpenSubFile, "OpenSubFile"},
|
{0x08010100, &File::OpenSubFile, "OpenSubFile"},
|
||||||
{0x080200C2, &File::Read, "Read"},
|
{0x080200C2, &File::Read, "Read"},
|
||||||
|
@ -195,7 +197,7 @@ void File::OpenLinkFile(Kernel::HLERequestContext& ctx) {
|
||||||
using Kernel::SharedPtr;
|
using Kernel::SharedPtr;
|
||||||
IPC::RequestParser rp(ctx, 0x080C, 0, 0);
|
IPC::RequestParser rp(ctx, 0x080C, 0, 0);
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||||
auto sessions = ServerSession::CreateSessionPair(GetName());
|
auto sessions = system.Kernel().CreateSessionPair(GetName());
|
||||||
auto server = std::get<SharedPtr<ServerSession>>(sessions);
|
auto server = std::get<SharedPtr<ServerSession>>(sessions);
|
||||||
ClientConnected(server);
|
ClientConnected(server);
|
||||||
|
|
||||||
|
@ -243,7 +245,7 @@ void File::OpenSubFile(Kernel::HLERequestContext& ctx) {
|
||||||
using Kernel::ClientSession;
|
using Kernel::ClientSession;
|
||||||
using Kernel::ServerSession;
|
using Kernel::ServerSession;
|
||||||
using Kernel::SharedPtr;
|
using Kernel::SharedPtr;
|
||||||
auto sessions = ServerSession::CreateSessionPair(GetName());
|
auto sessions = system.Kernel().CreateSessionPair(GetName());
|
||||||
auto server = std::get<SharedPtr<ServerSession>>(sessions);
|
auto server = std::get<SharedPtr<ServerSession>>(sessions);
|
||||||
ClientConnected(server);
|
ClientConnected(server);
|
||||||
|
|
||||||
|
@ -258,7 +260,7 @@ void File::OpenSubFile(Kernel::HLERequestContext& ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ClientSession> File::Connect() {
|
Kernel::SharedPtr<Kernel::ClientSession> File::Connect() {
|
||||||
auto sessions = Kernel::ServerSession::CreateSessionPair(GetName());
|
auto sessions = system.Kernel().CreateSessionPair(GetName());
|
||||||
auto server = std::get<Kernel::SharedPtr<Kernel::ServerSession>>(sessions);
|
auto server = std::get<Kernel::SharedPtr<Kernel::ServerSession>>(sessions);
|
||||||
ClientConnected(server);
|
ClientConnected(server);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Service::FS {
|
namespace Service::FS {
|
||||||
|
|
||||||
struct FileSessionSlot : public Kernel::SessionRequestHandler::SessionDataBase {
|
struct FileSessionSlot : public Kernel::SessionRequestHandler::SessionDataBase {
|
||||||
|
@ -21,7 +25,8 @@ struct FileSessionSlot : public Kernel::SessionRequestHandler::SessionDataBase {
|
||||||
// Consider splitting ServiceFramework interface.
|
// Consider splitting ServiceFramework interface.
|
||||||
class File final : public ServiceFramework<File, FileSessionSlot> {
|
class File final : public ServiceFramework<File, FileSessionSlot> {
|
||||||
public:
|
public:
|
||||||
File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path);
|
File(Core::System& system, std::unique_ptr<FileSys::FileBackend>&& backend,
|
||||||
|
const FileSys::Path& path);
|
||||||
~File() = default;
|
~File() = default;
|
||||||
|
|
||||||
std::string GetName() const {
|
std::string GetName() const {
|
||||||
|
@ -53,6 +58,8 @@ private:
|
||||||
void GetPriority(Kernel::HLERequestContext& ctx);
|
void GetPriority(Kernel::HLERequestContext& ctx);
|
||||||
void OpenLinkFile(Kernel::HLERequestContext& ctx);
|
void OpenLinkFile(Kernel::HLERequestContext& ctx);
|
||||||
void OpenSubFile(Kernel::HLERequestContext& ctx);
|
void OpenSubFile(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
|
Core::System& system;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::FS
|
} // namespace Service::FS
|
||||||
|
|
|
@ -286,7 +286,7 @@ void FS_USER::OpenDirectory(Kernel::HLERequestContext& ctx) {
|
||||||
rb.Push(dir_res.Code());
|
rb.Push(dir_res.Code());
|
||||||
if (dir_res.Succeeded()) {
|
if (dir_res.Succeeded()) {
|
||||||
std::shared_ptr<Directory> directory = *dir_res;
|
std::shared_ptr<Directory> directory = *dir_res;
|
||||||
auto sessions = ServerSession::CreateSessionPair(directory->GetName());
|
auto sessions = system.Kernel().CreateSessionPair(directory->GetName());
|
||||||
directory->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions));
|
directory->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions));
|
||||||
rb.PushMoveObjects(std::get<SharedPtr<ClientSession>>(sessions));
|
rb.PushMoveObjects(std::get<SharedPtr<ClientSession>>(sessions));
|
||||||
} else {
|
} else {
|
||||||
|
@ -741,7 +741,8 @@ void FS_USER::GetSaveDataSecureValue(Kernel::HLERequestContext& ctx) {
|
||||||
rb.Push<u64>(0); // the secure value
|
rb.Push<u64>(0); // the secure value
|
||||||
}
|
}
|
||||||
|
|
||||||
FS_USER::FS_USER(ArchiveManager& archives) : ServiceFramework("fs:USER", 30), archives(archives) {
|
FS_USER::FS_USER(Core::System& system)
|
||||||
|
: ServiceFramework("fs:USER", 30), system(system), archives(system.ArchiveManager()) {
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0x000100C6, nullptr, "Dummy1"},
|
{0x000100C6, nullptr, "Dummy1"},
|
||||||
{0x040100C4, nullptr, "Control"},
|
{0x040100C4, nullptr, "Control"},
|
||||||
|
@ -860,6 +861,6 @@ FS_USER::FS_USER(ArchiveManager& archives) : ServiceFramework("fs:USER", 30), ar
|
||||||
|
|
||||||
void InstallInterfaces(Core::System& system) {
|
void InstallInterfaces(Core::System& system) {
|
||||||
auto& service_manager = system.ServiceManager();
|
auto& service_manager = system.ServiceManager();
|
||||||
std::make_shared<FS_USER>(system.ArchiveManager())->InstallAsService(service_manager);
|
std::make_shared<FS_USER>(system)->InstallAsService(service_manager);
|
||||||
}
|
}
|
||||||
} // namespace Service::FS
|
} // namespace Service::FS
|
||||||
|
|
|
@ -17,7 +17,7 @@ class ArchiveManager;
|
||||||
|
|
||||||
class FS_USER final : public ServiceFramework<FS_USER> {
|
class FS_USER final : public ServiceFramework<FS_USER> {
|
||||||
public:
|
public:
|
||||||
explicit FS_USER(ArchiveManager& archives);
|
explicit FS_USER(Core::System& system);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Initialize(Kernel::HLERequestContext& ctx);
|
void Initialize(Kernel::HLERequestContext& ctx);
|
||||||
|
@ -534,6 +534,7 @@ private:
|
||||||
|
|
||||||
u32 priority = -1; ///< For SetPriority and GetPriority service functions
|
u32 priority = -1; ///< For SetPriority and GetPriority service functions
|
||||||
|
|
||||||
|
Core::System& system;
|
||||||
ArchiveManager& archives;
|
ArchiveManager& archives;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -786,8 +786,8 @@ GSP_GPU::GSP_GPU(Core::System& system) : ServiceFramework("gsp::Gpu", 2), system
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
|
|
||||||
using Kernel::MemoryPermission;
|
using Kernel::MemoryPermission;
|
||||||
shared_memory = Kernel::SharedMemory::Create(nullptr, 0x1000, MemoryPermission::ReadWrite,
|
shared_memory = system.Kernel().CreateSharedMemory(
|
||||||
MemoryPermission::ReadWrite, 0,
|
nullptr, 0x1000, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, 0,
|
||||||
Kernel::MemoryRegion::BASE, "GSP:SharedMemory");
|
Kernel::MemoryRegion::BASE, "GSP:SharedMemory");
|
||||||
|
|
||||||
first_initialization = true;
|
first_initialization = true;
|
||||||
|
|
|
@ -359,16 +359,16 @@ std::shared_ptr<Module> Module::Interface::GetModule() const {
|
||||||
Module::Module(Core::System& system) : system(system) {
|
Module::Module(Core::System& system) : system(system) {
|
||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
|
|
||||||
shared_mem =
|
shared_mem = system.Kernel().CreateSharedMemory(nullptr, 0x1000, MemoryPermission::ReadWrite,
|
||||||
SharedMemory::Create(nullptr, 0x1000, MemoryPermission::ReadWrite, MemoryPermission::Read,
|
MemoryPermission::Read, 0, MemoryRegion::BASE,
|
||||||
0, MemoryRegion::BASE, "HID:SharedMemory");
|
"HID:SharedMemory");
|
||||||
|
|
||||||
// Create event handles
|
// Create event handles
|
||||||
event_pad_or_touch_1 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch1");
|
event_pad_or_touch_1 = system.Kernel().CreateEvent(ResetType::OneShot, "HID:EventPadOrTouch1");
|
||||||
event_pad_or_touch_2 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch2");
|
event_pad_or_touch_2 = system.Kernel().CreateEvent(ResetType::OneShot, "HID:EventPadOrTouch2");
|
||||||
event_accelerometer = Event::Create(ResetType::OneShot, "HID:EventAccelerometer");
|
event_accelerometer = system.Kernel().CreateEvent(ResetType::OneShot, "HID:EventAccelerometer");
|
||||||
event_gyroscope = Event::Create(ResetType::OneShot, "HID:EventGyroscope");
|
event_gyroscope = system.Kernel().CreateEvent(ResetType::OneShot, "HID:EventGyroscope");
|
||||||
event_debug_pad = Event::Create(ResetType::OneShot, "HID:EventDebugPad");
|
event_debug_pad = system.Kernel().CreateEvent(ResetType::OneShot, "HID:EventDebugPad");
|
||||||
|
|
||||||
// Register update callbacks
|
// Register update callbacks
|
||||||
pad_update_event =
|
pad_update_event =
|
||||||
|
|
|
@ -16,10 +16,10 @@ void InstallInterfaces(Core::System& system) {
|
||||||
auto& service_manager = system.ServiceManager();
|
auto& service_manager = system.ServiceManager();
|
||||||
std::make_shared<IR_U>()->InstallAsService(service_manager);
|
std::make_shared<IR_U>()->InstallAsService(service_manager);
|
||||||
|
|
||||||
auto ir_user = std::make_shared<IR_USER>();
|
auto ir_user = std::make_shared<IR_USER>(system);
|
||||||
ir_user->InstallAsService(service_manager);
|
ir_user->InstallAsService(service_manager);
|
||||||
|
|
||||||
auto ir_rst = std::make_shared<IR_RST>();
|
auto ir_rst = std::make_shared<IR_RST>(system);
|
||||||
ir_rst->InstallAsService(service_manager);
|
ir_rst->InstallAsService(service_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/kernel/event.h"
|
#include "core/hle/kernel/event.h"
|
||||||
|
@ -144,14 +145,14 @@ void IR_RST::Shutdown(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_IR, "called");
|
LOG_DEBUG(Service_IR, "called");
|
||||||
}
|
}
|
||||||
|
|
||||||
IR_RST::IR_RST() : ServiceFramework("ir:rst", 1) {
|
IR_RST::IR_RST(Core::System& system) : ServiceFramework("ir:rst", 1) {
|
||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
// Note: these two kernel objects are even available before Initialize service function is
|
// Note: these two kernel objects are even available before Initialize service function is
|
||||||
// called.
|
// called.
|
||||||
shared_memory =
|
shared_memory = system.Kernel().CreateSharedMemory(nullptr, 0x1000, MemoryPermission::ReadWrite,
|
||||||
SharedMemory::Create(nullptr, 0x1000, MemoryPermission::ReadWrite, MemoryPermission::Read,
|
MemoryPermission::Read, 0,
|
||||||
0, MemoryRegion::BASE, "IRRST:SharedMemory");
|
MemoryRegion::BASE, "IRRST:SharedMemory");
|
||||||
update_event = Event::Create(ResetType::OneShot, "IRRST:UpdateEvent");
|
update_event = system.Kernel().CreateEvent(ResetType::OneShot, "IRRST:UpdateEvent");
|
||||||
|
|
||||||
update_callback_id =
|
update_callback_id =
|
||||||
CoreTiming::RegisterEvent("IRRST:UpdateCallBack", [this](u64 userdata, s64 cycles_late) {
|
CoreTiming::RegisterEvent("IRRST:UpdateCallBack", [this](u64 userdata, s64 cycles_late) {
|
||||||
|
|
|
@ -39,7 +39,7 @@ union PadState {
|
||||||
/// Interface to "ir:rst" service
|
/// Interface to "ir:rst" service
|
||||||
class IR_RST final : public ServiceFramework<IR_RST> {
|
class IR_RST final : public ServiceFramework<IR_RST> {
|
||||||
public:
|
public:
|
||||||
IR_RST();
|
explicit IR_RST(Core::System& system);
|
||||||
~IR_RST();
|
~IR_RST();
|
||||||
void ReloadInputDevices();
|
void ReloadInputDevices();
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <boost/crc.hpp>
|
#include <boost/crc.hpp>
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/kernel/event.h"
|
#include "core/hle/kernel/event.h"
|
||||||
#include "core/hle/kernel/shared_memory.h"
|
#include "core/hle/kernel/shared_memory.h"
|
||||||
|
@ -380,7 +381,7 @@ void IR_USER::ReleaseReceivedData(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_TRACE(Service_IR, "called, count={}", count);
|
LOG_TRACE(Service_IR, "called, count={}", count);
|
||||||
}
|
}
|
||||||
|
|
||||||
IR_USER::IR_USER() : ServiceFramework("ir:USER", 1) {
|
IR_USER::IR_USER(Core::System& system) : ServiceFramework("ir:USER", 1) {
|
||||||
const FunctionInfo functions[] = {
|
const FunctionInfo functions[] = {
|
||||||
{0x00010182, nullptr, "InitializeIrNop"},
|
{0x00010182, nullptr, "InitializeIrNop"},
|
||||||
{0x00020000, &IR_USER::FinalizeIrNop, "FinalizeIrNop"},
|
{0x00020000, &IR_USER::FinalizeIrNop, "FinalizeIrNop"},
|
||||||
|
@ -413,9 +414,9 @@ IR_USER::IR_USER() : ServiceFramework("ir:USER", 1) {
|
||||||
|
|
||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
|
|
||||||
conn_status_event = Event::Create(ResetType::OneShot, "IR:ConnectionStatusEvent");
|
conn_status_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:ConnectionStatusEvent");
|
||||||
send_event = Event::Create(ResetType::OneShot, "IR:SendEvent");
|
send_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:SendEvent");
|
||||||
receive_event = Event::Create(ResetType::OneShot, "IR:ReceiveEvent");
|
receive_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:ReceiveEvent");
|
||||||
|
|
||||||
extra_hid =
|
extra_hid =
|
||||||
std::make_unique<ExtraHID>([this](const std::vector<u8>& data) { PutToReceive(data); });
|
std::make_unique<ExtraHID>([this](const std::vector<u8>& data) { PutToReceive(data); });
|
||||||
|
|
|
@ -55,7 +55,7 @@ private:
|
||||||
/// Interface to "ir:USER" service
|
/// Interface to "ir:USER" service
|
||||||
class IR_USER final : public ServiceFramework<IR_USER> {
|
class IR_USER final : public ServiceFramework<IR_USER> {
|
||||||
public:
|
public:
|
||||||
IR_USER();
|
explicit IR_USER(Core::System& system);
|
||||||
~IR_USER();
|
~IR_USER();
|
||||||
|
|
||||||
void ReloadInputDevices();
|
void ReloadInputDevices();
|
||||||
|
|
|
@ -29,6 +29,11 @@ enum class SampleRate : u8 {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MIC_U::Impl {
|
struct MIC_U::Impl {
|
||||||
|
explicit Impl(Core::System& system) {
|
||||||
|
buffer_full_event =
|
||||||
|
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "MIC_U::buffer_full_event");
|
||||||
|
}
|
||||||
|
|
||||||
void MapSharedMem(Kernel::HLERequestContext& ctx) {
|
void MapSharedMem(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx, 0x01, 1, 2};
|
IPC::RequestParser rp{ctx, 0x01, 1, 2};
|
||||||
const u32 size = rp.Pop<u32>();
|
const u32 size = rp.Pop<u32>();
|
||||||
|
@ -187,8 +192,7 @@ struct MIC_U::Impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 client_version = 0;
|
u32 client_version = 0;
|
||||||
Kernel::SharedPtr<Kernel::Event> buffer_full_event =
|
Kernel::SharedPtr<Kernel::Event> buffer_full_event;
|
||||||
Kernel::Event::Create(Kernel::ResetType::OneShot, "MIC_U::buffer_full_event");
|
|
||||||
Kernel::SharedPtr<Kernel::SharedMemory> shared_memory;
|
Kernel::SharedPtr<Kernel::SharedMemory> shared_memory;
|
||||||
u8 mic_gain = 0;
|
u8 mic_gain = 0;
|
||||||
bool mic_power = false;
|
bool mic_power = false;
|
||||||
|
@ -266,7 +270,8 @@ void MIC_U::SetClientVersion(Kernel::HLERequestContext& ctx) {
|
||||||
impl->SetClientVersion(ctx);
|
impl->SetClientVersion(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
MIC_U::MIC_U() : ServiceFramework{"mic:u", 1}, impl{std::make_unique<Impl>()} {
|
MIC_U::MIC_U(Core::System& system)
|
||||||
|
: ServiceFramework{"mic:u", 1}, impl{std::make_unique<Impl>(system)} {
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0x00010042, &MIC_U::MapSharedMem, "MapSharedMem"},
|
{0x00010042, &MIC_U::MapSharedMem, "MapSharedMem"},
|
||||||
{0x00020000, &MIC_U::UnmapSharedMem, "UnmapSharedMem"},
|
{0x00020000, &MIC_U::UnmapSharedMem, "UnmapSharedMem"},
|
||||||
|
@ -293,7 +298,7 @@ MIC_U::~MIC_U() = default;
|
||||||
|
|
||||||
void InstallInterfaces(Core::System& system) {
|
void InstallInterfaces(Core::System& system) {
|
||||||
auto& service_manager = system.ServiceManager();
|
auto& service_manager = system.ServiceManager();
|
||||||
std::make_shared<MIC_U>()->InstallAsService(service_manager);
|
std::make_shared<MIC_U>(system)->InstallAsService(service_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::MIC
|
} // namespace Service::MIC
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace Service::MIC {
|
||||||
|
|
||||||
class MIC_U final : public ServiceFramework<MIC_U> {
|
class MIC_U final : public ServiceFramework<MIC_U> {
|
||||||
public:
|
public:
|
||||||
MIC_U();
|
explicit MIC_U(Core::System& system);
|
||||||
~MIC_U();
|
~MIC_U();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -140,18 +140,18 @@ Module::Interface::Interface(std::shared_ptr<Module> nfc, const char* name, u32
|
||||||
|
|
||||||
Module::Interface::~Interface() = default;
|
Module::Interface::~Interface() = default;
|
||||||
|
|
||||||
Module::Module() {
|
Module::Module(Core::System& system) {
|
||||||
tag_in_range_event =
|
tag_in_range_event =
|
||||||
Kernel::Event::Create(Kernel::ResetType::OneShot, "NFC::tag_in_range_event");
|
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NFC::tag_in_range_event");
|
||||||
tag_out_of_range_event =
|
tag_out_of_range_event =
|
||||||
Kernel::Event::Create(Kernel::ResetType::OneShot, "NFC::tag_out_range_event");
|
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NFC::tag_out_range_event");
|
||||||
}
|
}
|
||||||
|
|
||||||
Module::~Module() = default;
|
Module::~Module() = default;
|
||||||
|
|
||||||
void InstallInterfaces(Core::System& system) {
|
void InstallInterfaces(Core::System& system) {
|
||||||
auto& service_manager = system.ServiceManager();
|
auto& service_manager = system.ServiceManager();
|
||||||
auto nfc = std::make_shared<Module>();
|
auto nfc = std::make_shared<Module>(system);
|
||||||
std::make_shared<NFC_M>(nfc)->InstallAsService(service_manager);
|
std::make_shared<NFC_M>(nfc)->InstallAsService(service_manager);
|
||||||
std::make_shared<NFC_U>(nfc)->InstallAsService(service_manager);
|
std::make_shared<NFC_U>(nfc)->InstallAsService(service_manager);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ enum class CommunicationStatus : u8 {
|
||||||
|
|
||||||
class Module final {
|
class Module final {
|
||||||
public:
|
public:
|
||||||
Module();
|
explicit Module(Core::System& system);
|
||||||
~Module();
|
~Module();
|
||||||
|
|
||||||
class Interface : public ServiceFramework<Interface> {
|
class Interface : public ServiceFramework<Interface> {
|
||||||
|
|
|
@ -14,7 +14,7 @@ void InstallInterfaces(Core::System& system) {
|
||||||
auto& service_manager = system.ServiceManager();
|
auto& service_manager = system.ServiceManager();
|
||||||
std::make_shared<NIM_AOC>()->InstallAsService(service_manager);
|
std::make_shared<NIM_AOC>()->InstallAsService(service_manager);
|
||||||
std::make_shared<NIM_S>()->InstallAsService(service_manager);
|
std::make_shared<NIM_S>()->InstallAsService(service_manager);
|
||||||
std::make_shared<NIM_U>()->InstallAsService(service_manager);
|
std::make_shared<NIM_U>(system)->InstallAsService(service_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::NIM
|
} // namespace Service::NIM
|
||||||
|
|
|
@ -2,13 +2,14 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/kernel/event.h"
|
#include "core/hle/kernel/event.h"
|
||||||
#include "core/hle/service/nim/nim_u.h"
|
#include "core/hle/service/nim/nim_u.h"
|
||||||
|
|
||||||
namespace Service::NIM {
|
namespace Service::NIM {
|
||||||
|
|
||||||
NIM_U::NIM_U() : ServiceFramework("nim:u", 2) {
|
NIM_U::NIM_U(Core::System& system) : ServiceFramework("nim:u", 2) {
|
||||||
const FunctionInfo functions[] = {
|
const FunctionInfo functions[] = {
|
||||||
{0x00010000, nullptr, "StartSysUpdate"},
|
{0x00010000, nullptr, "StartSysUpdate"},
|
||||||
{0x00020000, nullptr, "GetUpdateDownloadProgress"},
|
{0x00020000, nullptr, "GetUpdateDownloadProgress"},
|
||||||
|
@ -20,7 +21,7 @@ NIM_U::NIM_U() : ServiceFramework("nim:u", 2) {
|
||||||
};
|
};
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
nim_system_update_event =
|
nim_system_update_event =
|
||||||
Kernel::Event::Create(Kernel::ResetType::OneShot, "NIM System Update Event");
|
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NIM System Update Event");
|
||||||
}
|
}
|
||||||
|
|
||||||
NIM_U::~NIM_U() = default;
|
NIM_U::~NIM_U() = default;
|
||||||
|
|
|
@ -6,11 +6,15 @@
|
||||||
|
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Service::NIM {
|
namespace Service::NIM {
|
||||||
|
|
||||||
class NIM_U final : public ServiceFramework<NIM_U> {
|
class NIM_U final : public ServiceFramework<NIM_U> {
|
||||||
public:
|
public:
|
||||||
NIM_U();
|
explicit NIM_U(Core::System& system);
|
||||||
~NIM_U();
|
~NIM_U();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -839,7 +839,7 @@ void NWM_UDS::Bind(Kernel::HLERequestContext& ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new event for this bind node.
|
// Create a new event for this bind node.
|
||||||
auto event = Kernel::Event::Create(Kernel::ResetType::OneShot,
|
auto event = system.Kernel().CreateEvent(Kernel::ResetType::OneShot,
|
||||||
"NWM::BindNodeEvent" + std::to_string(bind_node_id));
|
"NWM::BindNodeEvent" + std::to_string(bind_node_id));
|
||||||
std::lock_guard<std::mutex> lock(connection_status_mutex);
|
std::lock_guard<std::mutex> lock(connection_status_mutex);
|
||||||
|
|
||||||
|
@ -1355,7 +1355,7 @@ static void BeaconBroadcastCallback(u64 userdata, s64 cycles_late) {
|
||||||
beacon_broadcast_event, 0);
|
beacon_broadcast_event, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
NWM_UDS::NWM_UDS(Core::System& system) : ServiceFramework("nwm::UDS") {
|
NWM_UDS::NWM_UDS(Core::System& system) : ServiceFramework("nwm::UDS"), system(system) {
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0x000102C2, nullptr, "Initialize (deprecated)"},
|
{0x000102C2, nullptr, "Initialize (deprecated)"},
|
||||||
{0x00020000, nullptr, "Scrap"},
|
{0x00020000, nullptr, "Scrap"},
|
||||||
|
@ -1388,7 +1388,7 @@ NWM_UDS::NWM_UDS(Core::System& system) : ServiceFramework("nwm::UDS") {
|
||||||
{0x00220402, nullptr, "ScanOnConnection"},
|
{0x00220402, nullptr, "ScanOnConnection"},
|
||||||
};
|
};
|
||||||
connection_status_event =
|
connection_status_event =
|
||||||
Kernel::Event::Create(Kernel::ResetType::OneShot, "NWM::connection_status_event");
|
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NWM::connection_status_event");
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,8 @@ public:
|
||||||
~NWM_UDS();
|
~NWM_UDS();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Core::System& system;
|
||||||
|
|
||||||
void UpdateNetworkAttribute(Kernel::HLERequestContext& ctx);
|
void UpdateNetworkAttribute(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -143,11 +143,11 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager)
|
||||||
port->SetHleHandler(shared_from_this());
|
port->SetHleHandler(shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceFrameworkBase::InstallAsNamedPort() {
|
void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelSystem& kernel) {
|
||||||
ASSERT(port == nullptr);
|
ASSERT(port == nullptr);
|
||||||
SharedPtr<ServerPort> server_port;
|
SharedPtr<ServerPort> server_port;
|
||||||
SharedPtr<ClientPort> client_port;
|
SharedPtr<ClientPort> client_port;
|
||||||
std::tie(server_port, client_port) = ServerPort::CreatePortPair(max_sessions, service_name);
|
std::tie(server_port, client_port) = kernel.CreatePortPair(max_sessions, service_name);
|
||||||
server_port->SetHleHandler(shared_from_this());
|
server_port->SetHleHandler(shared_from_this());
|
||||||
AddNamedPort(service_name, std::move(client_port));
|
AddNamedPort(service_name, std::move(client_port));
|
||||||
}
|
}
|
||||||
|
@ -235,8 +235,8 @@ static bool AttemptLLE(const ServiceModuleInfo& service_module) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize ServiceManager
|
/// Initialize ServiceManager
|
||||||
void Init(Core::System& core, std::shared_ptr<SM::ServiceManager>& sm) {
|
void Init(Core::System& core) {
|
||||||
SM::ServiceManager::InstallInterfaces(sm);
|
SM::ServiceManager::InstallInterfaces(core);
|
||||||
|
|
||||||
for (const auto& service_module : service_module_map) {
|
for (const auto& service_module : service_module_map) {
|
||||||
if (!AttemptLLE(service_module) && service_module.init_function != nullptr)
|
if (!AttemptLLE(service_module) && service_module.init_function != nullptr)
|
||||||
|
|
|
@ -20,6 +20,7 @@ class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
class KernelSystem;
|
||||||
class ClientPort;
|
class ClientPort;
|
||||||
class ServerPort;
|
class ServerPort;
|
||||||
class ServerSession;
|
class ServerSession;
|
||||||
|
@ -59,7 +60,7 @@ public:
|
||||||
/// Creates a port pair and registers this service with the given ServiceManager.
|
/// Creates a port pair and registers this service with the given ServiceManager.
|
||||||
void InstallAsService(SM::ServiceManager& service_manager);
|
void InstallAsService(SM::ServiceManager& service_manager);
|
||||||
/// Creates a port pair and registers it on the kernel's global port registry.
|
/// Creates a port pair and registers it on the kernel's global port registry.
|
||||||
void InstallAsNamedPort();
|
void InstallAsNamedPort(Kernel::KernelSystem& kernel);
|
||||||
|
|
||||||
void HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> server_session) override;
|
void HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> server_session) override;
|
||||||
|
|
||||||
|
@ -184,7 +185,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Initialize ServiceManager
|
/// Initialize ServiceManager
|
||||||
void Init(Core::System& system, std::shared_ptr<SM::ServiceManager>& sm);
|
void Init(Core::System& system);
|
||||||
|
|
||||||
/// Shutdown ServiceManager
|
/// Shutdown ServiceManager
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/hle/kernel/client_session.h"
|
#include "core/hle/kernel/client_session.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
|
@ -21,12 +22,14 @@ static ResultCode ValidateServiceName(const std::string& name) {
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceManager::InstallInterfaces(std::shared_ptr<ServiceManager> self) {
|
ServiceManager::ServiceManager(Core::System& system) : system(system) {}
|
||||||
ASSERT(self->srv_interface.expired());
|
|
||||||
|
|
||||||
auto srv = std::make_shared<SRV>(self);
|
void ServiceManager::InstallInterfaces(Core::System& system) {
|
||||||
srv->InstallAsNamedPort();
|
ASSERT(system.ServiceManager().srv_interface.expired());
|
||||||
self->srv_interface = srv;
|
|
||||||
|
auto srv = std::make_shared<SRV>(system);
|
||||||
|
srv->InstallAsNamedPort(system.Kernel());
|
||||||
|
system.ServiceManager().srv_interface = srv;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> ServiceManager::RegisterService(
|
ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> ServiceManager::RegisterService(
|
||||||
|
@ -39,7 +42,7 @@ ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> ServiceManager::RegisterService
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ServerPort> server_port;
|
Kernel::SharedPtr<Kernel::ServerPort> server_port;
|
||||||
Kernel::SharedPtr<Kernel::ClientPort> client_port;
|
Kernel::SharedPtr<Kernel::ClientPort> client_port;
|
||||||
std::tie(server_port, client_port) = Kernel::ServerPort::CreatePortPair(max_sessions, name);
|
std::tie(server_port, client_port) = system.Kernel().CreatePortPair(max_sessions, name);
|
||||||
|
|
||||||
registered_services.emplace(std::move(name), std::move(client_port));
|
registered_services.emplace(std::move(name), std::move(client_port));
|
||||||
return MakeResult<Kernel::SharedPtr<Kernel::ServerPort>>(std::move(server_port));
|
return MakeResult<Kernel::SharedPtr<Kernel::ServerPort>>(std::move(server_port));
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
class ClientSession;
|
class ClientSession;
|
||||||
class SessionRequestHandler;
|
class SessionRequestHandler;
|
||||||
|
@ -39,7 +43,9 @@ constexpr ResultCode ERR_ALREADY_REGISTERED(ErrorDescription::AlreadyExists, Err
|
||||||
|
|
||||||
class ServiceManager {
|
class ServiceManager {
|
||||||
public:
|
public:
|
||||||
static void InstallInterfaces(std::shared_ptr<ServiceManager> self);
|
static void InstallInterfaces(Core::System& system);
|
||||||
|
|
||||||
|
explicit ServiceManager(Core::System& system);
|
||||||
|
|
||||||
ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> RegisterService(std::string name,
|
ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> RegisterService(std::string name,
|
||||||
unsigned int max_sessions);
|
unsigned int max_sessions);
|
||||||
|
@ -63,6 +69,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Core::System& system;
|
||||||
std::weak_ptr<SRV> srv_interface;
|
std::weak_ptr<SRV> srv_interface;
|
||||||
|
|
||||||
/// Map of registered services, retrieved using GetServicePort or ConnectToService.
|
/// Map of registered services, retrieved using GetServicePort or ConnectToService.
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/hle/ipc.h"
|
#include "core/hle/ipc.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/kernel/client_port.h"
|
#include "core/hle/kernel/client_port.h"
|
||||||
|
@ -62,7 +63,7 @@ void SRV::EnableNotification(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp(ctx, 0x2, 0, 0);
|
IPC::RequestParser rp(ctx, 0x2, 0, 0);
|
||||||
|
|
||||||
notification_semaphore =
|
notification_semaphore =
|
||||||
Kernel::Semaphore::Create(0, MAX_PENDING_NOTIFICATIONS, "SRV:Notification").Unwrap();
|
system.Kernel().CreateSemaphore(0, MAX_PENDING_NOTIFICATIONS, "SRV:Notification").Unwrap();
|
||||||
|
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
@ -103,7 +104,7 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) {
|
||||||
Kernel::HLERequestContext& ctx,
|
Kernel::HLERequestContext& ctx,
|
||||||
Kernel::ThreadWakeupReason reason) {
|
Kernel::ThreadWakeupReason reason) {
|
||||||
LOG_ERROR(Service_SRV, "called service={} wakeup", name);
|
LOG_ERROR(Service_SRV, "called service={} wakeup", name);
|
||||||
auto client_port = service_manager->GetServicePort(name);
|
auto client_port = system.ServiceManager().GetServicePort(name);
|
||||||
|
|
||||||
auto session = client_port.Unwrap()->Connect();
|
auto session = client_port.Unwrap()->Connect();
|
||||||
if (session.Succeeded()) {
|
if (session.Succeeded()) {
|
||||||
|
@ -122,7 +123,7 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto client_port = service_manager->GetServicePort(name);
|
auto client_port = system.ServiceManager().GetServicePort(name);
|
||||||
if (client_port.Failed()) {
|
if (client_port.Failed()) {
|
||||||
if (wait_until_available && client_port.Code() == ERR_SERVICE_NOT_REGISTERED) {
|
if (wait_until_available && client_port.Code() == ERR_SERVICE_NOT_REGISTERED) {
|
||||||
LOG_INFO(Service_SRV, "called service={} delayed", name);
|
LOG_INFO(Service_SRV, "called service={} delayed", name);
|
||||||
|
@ -223,7 +224,7 @@ void SRV::RegisterService(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
std::string name(name_buf.data(), std::min(name_len, name_buf.size()));
|
std::string name(name_buf.data(), std::min(name_len, name_buf.size()));
|
||||||
|
|
||||||
auto port = service_manager->RegisterService(name, max_sessions);
|
auto port = system.ServiceManager().RegisterService(name, max_sessions);
|
||||||
|
|
||||||
if (port.Failed()) {
|
if (port.Failed()) {
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||||
|
@ -243,8 +244,7 @@ void SRV::RegisterService(Kernel::HLERequestContext& ctx) {
|
||||||
rb.PushMoveObjects(port.Unwrap());
|
rb.PushMoveObjects(port.Unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
SRV::SRV(std::shared_ptr<ServiceManager> service_manager)
|
SRV::SRV(Core::System& system) : ServiceFramework("srv:", 4), system(system) {
|
||||||
: ServiceFramework("srv:", 4), service_manager(std::move(service_manager)) {
|
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0x00010002, &SRV::RegisterClient, "RegisterClient"},
|
{0x00010002, &SRV::RegisterClient, "RegisterClient"},
|
||||||
{0x00020000, &SRV::EnableNotification, "EnableNotification"},
|
{0x00020000, &SRV::EnableNotification, "EnableNotification"},
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
class HLERequestContext;
|
class HLERequestContext;
|
||||||
class Semaphore;
|
class Semaphore;
|
||||||
|
@ -18,7 +22,7 @@ namespace Service::SM {
|
||||||
/// Interface to "srv:" service
|
/// Interface to "srv:" service
|
||||||
class SRV final : public ServiceFramework<SRV> {
|
class SRV final : public ServiceFramework<SRV> {
|
||||||
public:
|
public:
|
||||||
explicit SRV(std::shared_ptr<ServiceManager> service_manager);
|
explicit SRV(Core::System& system);
|
||||||
~SRV();
|
~SRV();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -30,7 +34,7 @@ private:
|
||||||
void PublishToSubscriber(Kernel::HLERequestContext& ctx);
|
void PublishToSubscriber(Kernel::HLERequestContext& ctx);
|
||||||
void RegisterService(Kernel::HLERequestContext& ctx);
|
void RegisterService(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
std::shared_ptr<ServiceManager> service_manager;
|
Core::System& system;
|
||||||
Kernel::SharedPtr<Kernel::Semaphore> notification_semaphore;
|
Kernel::SharedPtr<Kernel::Semaphore> notification_semaphore;
|
||||||
std::unordered_map<std::string, Kernel::SharedPtr<Kernel::Event>>
|
std::unordered_map<std::string, Kernel::SharedPtr<Kernel::Event>>
|
||||||
get_service_handle_delayed_map;
|
get_service_handle_delayed_map;
|
||||||
|
|
|
@ -632,7 +632,7 @@ void Y2R_U::GetPackageParameter(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_Y2R, "called");
|
LOG_DEBUG(Service_Y2R, "called");
|
||||||
}
|
}
|
||||||
|
|
||||||
Y2R_U::Y2R_U() : ServiceFramework("y2r:u", 1) {
|
Y2R_U::Y2R_U(Core::System& system) : ServiceFramework("y2r:u", 1) {
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0x00010040, &Y2R_U::SetInputFormat, "SetInputFormat"},
|
{0x00010040, &Y2R_U::SetInputFormat, "SetInputFormat"},
|
||||||
{0x00020000, &Y2R_U::GetInputFormat, "GetInputFormat"},
|
{0x00020000, &Y2R_U::GetInputFormat, "GetInputFormat"},
|
||||||
|
@ -682,14 +682,14 @@ Y2R_U::Y2R_U() : ServiceFramework("y2r:u", 1) {
|
||||||
};
|
};
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
|
|
||||||
completion_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "Y2R:Completed");
|
completion_event = system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "Y2R:Completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
Y2R_U::~Y2R_U() = default;
|
Y2R_U::~Y2R_U() = default;
|
||||||
|
|
||||||
void InstallInterfaces(Core::System& system) {
|
void InstallInterfaces(Core::System& system) {
|
||||||
auto& service_manager = system.ServiceManager();
|
auto& service_manager = system.ServiceManager();
|
||||||
std::make_shared<Y2R_U>()->InstallAsService(service_manager);
|
std::make_shared<Y2R_U>(system)->InstallAsService(service_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::Y2R
|
} // namespace Service::Y2R
|
||||||
|
|
|
@ -149,7 +149,7 @@ static_assert(sizeof(ConversionParameters) == 12, "ConversionParameters struct h
|
||||||
|
|
||||||
class Y2R_U final : public ServiceFramework<Y2R_U> {
|
class Y2R_U final : public ServiceFramework<Y2R_U> {
|
||||||
public:
|
public:
|
||||||
Y2R_U();
|
explicit Y2R_U(Core::System& system);
|
||||||
~Y2R_U() override;
|
~Y2R_U() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -217,7 +217,7 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the CodeSet
|
// Create the CodeSet
|
||||||
SharedPtr<CodeSet> code_set = CodeSet::Create("", 0);
|
SharedPtr<CodeSet> code_set = Core::System::GetInstance().Kernel().CreateCodeSet("", 0);
|
||||||
|
|
||||||
code_set->CodeSegment().offset = loadinfo.seg_ptrs[0] - program_image.data();
|
code_set->CodeSegment().offset = loadinfo.seg_ptrs[0] - program_image.data();
|
||||||
code_set->CodeSegment().addr = loadinfo.seg_addrs[0];
|
code_set->CodeSegment().addr = loadinfo.seg_addrs[0];
|
||||||
|
@ -267,13 +267,13 @@ ResultStatus AppLoader_THREEDSX::Load(Kernel::SharedPtr<Kernel::Process>& proces
|
||||||
return ResultStatus::Error;
|
return ResultStatus::Error;
|
||||||
codeset->name = filename;
|
codeset->name = filename;
|
||||||
|
|
||||||
process = Kernel::Process::Create(std::move(codeset));
|
process = Core::System::GetInstance().Kernel().CreateProcess(std::move(codeset));
|
||||||
process->svc_access_mask.set();
|
process->svc_access_mask.set();
|
||||||
process->address_mappings = default_address_mappings;
|
process->address_mappings = default_address_mappings;
|
||||||
|
|
||||||
// Attach the default resource limit (APPLICATION) to the process
|
// Attach the default resource limit (APPLICATION) to the process
|
||||||
process->resource_limit =
|
process->resource_limit = Core::System::GetInstance().Kernel().ResourceLimit().GetForCategory(
|
||||||
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
|
Kernel::ResourceLimitCategory::APPLICATION);
|
||||||
|
|
||||||
process->Run(48, Kernel::DEFAULT_STACK_SIZE);
|
process->Run(48, Kernel::DEFAULT_STACK_SIZE);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
#include "core/hle/kernel/resource_limit.h"
|
#include "core/hle/kernel/resource_limit.h"
|
||||||
#include "core/loader/elf.h"
|
#include "core/loader/elf.h"
|
||||||
|
@ -299,7 +300,7 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
|
||||||
std::vector<u8> program_image(total_image_size);
|
std::vector<u8> program_image(total_image_size);
|
||||||
std::size_t current_image_position = 0;
|
std::size_t current_image_position = 0;
|
||||||
|
|
||||||
SharedPtr<CodeSet> codeset = CodeSet::Create("", 0);
|
SharedPtr<CodeSet> codeset = Core::System::GetInstance().Kernel().CreateCodeSet("", 0);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < header->e_phnum; ++i) {
|
for (unsigned int i = 0; i < header->e_phnum; ++i) {
|
||||||
Elf32_Phdr* p = &segments[i];
|
Elf32_Phdr* p = &segments[i];
|
||||||
|
@ -395,13 +396,13 @@ ResultStatus AppLoader_ELF::Load(Kernel::SharedPtr<Kernel::Process>& process) {
|
||||||
SharedPtr<CodeSet> codeset = elf_reader.LoadInto(Memory::PROCESS_IMAGE_VADDR);
|
SharedPtr<CodeSet> codeset = elf_reader.LoadInto(Memory::PROCESS_IMAGE_VADDR);
|
||||||
codeset->name = filename;
|
codeset->name = filename;
|
||||||
|
|
||||||
process = Kernel::Process::Create(std::move(codeset));
|
process = Core::System::GetInstance().Kernel().CreateProcess(std::move(codeset));
|
||||||
process->svc_access_mask.set();
|
process->svc_access_mask.set();
|
||||||
process->address_mappings = default_address_mappings;
|
process->address_mappings = default_address_mappings;
|
||||||
|
|
||||||
// Attach the default resource limit (APPLICATION) to the process
|
// Attach the default resource limit (APPLICATION) to the process
|
||||||
process->resource_limit =
|
process->resource_limit = Core::System::GetInstance().Kernel().ResourceLimit().GetForCategory(
|
||||||
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
|
Kernel::ResourceLimitCategory::APPLICATION);
|
||||||
|
|
||||||
process->Run(48, Kernel::DEFAULT_STACK_SIZE);
|
process->Run(48, Kernel::DEFAULT_STACK_SIZE);
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,8 @@ ResultStatus AppLoader_NCCH::LoadExec(Kernel::SharedPtr<Kernel::Process>& proces
|
||||||
std::string process_name = Common::StringFromFixedZeroTerminatedBuffer(
|
std::string process_name = Common::StringFromFixedZeroTerminatedBuffer(
|
||||||
(const char*)overlay_ncch->exheader_header.codeset_info.name, 8);
|
(const char*)overlay_ncch->exheader_header.codeset_info.name, 8);
|
||||||
|
|
||||||
SharedPtr<CodeSet> codeset = CodeSet::Create(process_name, program_id);
|
SharedPtr<CodeSet> codeset =
|
||||||
|
Core::System::GetInstance().Kernel().CreateCodeSet(process_name, program_id);
|
||||||
|
|
||||||
codeset->CodeSegment().offset = 0;
|
codeset->CodeSegment().offset = 0;
|
||||||
codeset->CodeSegment().addr = overlay_ncch->exheader_header.codeset_info.text.address;
|
codeset->CodeSegment().addr = overlay_ncch->exheader_header.codeset_info.text.address;
|
||||||
|
@ -103,11 +104,12 @@ ResultStatus AppLoader_NCCH::LoadExec(Kernel::SharedPtr<Kernel::Process>& proces
|
||||||
codeset->entrypoint = codeset->CodeSegment().addr;
|
codeset->entrypoint = codeset->CodeSegment().addr;
|
||||||
codeset->memory = std::make_shared<std::vector<u8>>(std::move(code));
|
codeset->memory = std::make_shared<std::vector<u8>>(std::move(code));
|
||||||
|
|
||||||
process = Kernel::Process::Create(std::move(codeset));
|
process = Core::System::GetInstance().Kernel().CreateProcess(std::move(codeset));
|
||||||
|
|
||||||
// Attach a resource limit to the process based on the resource limit category
|
// Attach a resource limit to the process based on the resource limit category
|
||||||
process->resource_limit =
|
process->resource_limit =
|
||||||
Kernel::ResourceLimit::GetForCategory(static_cast<Kernel::ResourceLimitCategory>(
|
Core::System::GetInstance().Kernel().ResourceLimit().GetForCategory(
|
||||||
|
static_cast<Kernel::ResourceLimitCategory>(
|
||||||
overlay_ncch->exheader_header.arm11_system_local_caps.resource_limit_category));
|
overlay_ncch->exheader_header.arm11_system_local_caps.resource_limit_category));
|
||||||
|
|
||||||
// Set the default CPU core for this process
|
// Set the default CPU core for this process
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "core/memory_setup.h"
|
#include "core/memory_setup.h"
|
||||||
|
@ -15,7 +16,10 @@ static Memory::PageTable* page_table = nullptr;
|
||||||
TestEnvironment::TestEnvironment(bool mutable_memory_)
|
TestEnvironment::TestEnvironment(bool mutable_memory_)
|
||||||
: mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) {
|
: mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) {
|
||||||
|
|
||||||
Kernel::g_current_process = Kernel::Process::Create(Kernel::CodeSet::Create("", 0));
|
CoreTiming::Init();
|
||||||
|
kernel = std::make_unique<Kernel::KernelSystem>(0);
|
||||||
|
|
||||||
|
Kernel::g_current_process = kernel->CreateProcess(kernel->CreateCodeSet("", 0));
|
||||||
page_table = &Kernel::g_current_process->vm_manager.page_table;
|
page_table = &Kernel::g_current_process->vm_manager.page_table;
|
||||||
|
|
||||||
page_table->pointers.fill(nullptr);
|
page_table->pointers.fill(nullptr);
|
||||||
|
@ -30,6 +34,8 @@ TestEnvironment::TestEnvironment(bool mutable_memory_)
|
||||||
TestEnvironment::~TestEnvironment() {
|
TestEnvironment::~TestEnvironment() {
|
||||||
Memory::UnmapRegion(*page_table, 0x80000000, 0x80000000);
|
Memory::UnmapRegion(*page_table, 0x80000000, 0x80000000);
|
||||||
Memory::UnmapRegion(*page_table, 0x00000000, 0x80000000);
|
Memory::UnmapRegion(*page_table, 0x00000000, 0x80000000);
|
||||||
|
|
||||||
|
CoreTiming::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestEnvironment::SetMemory64(VAddr vaddr, u64 value) {
|
void TestEnvironment::SetMemory64(VAddr vaddr, u64 value) {
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/mmio.h"
|
#include "core/mmio.h"
|
||||||
|
|
||||||
namespace ArmTests {
|
namespace ArmTests {
|
||||||
|
@ -79,6 +79,8 @@ private:
|
||||||
bool mutable_memory;
|
bool mutable_memory;
|
||||||
std::shared_ptr<TestMemory> test_memory;
|
std::shared_ptr<TestMemory> test_memory;
|
||||||
std::vector<WriteRecord> write_records;
|
std::vector<WriteRecord> write_records;
|
||||||
|
|
||||||
|
std::unique_ptr<Kernel::KernelSystem> kernel;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ArmTests
|
} // namespace ArmTests
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <catch2/catch.hpp>
|
#include <catch2/catch.hpp>
|
||||||
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/ipc.h"
|
#include "core/hle/ipc.h"
|
||||||
#include "core/hle/kernel/client_port.h"
|
#include "core/hle/kernel/client_port.h"
|
||||||
#include "core/hle/kernel/client_session.h"
|
#include "core/hle/kernel/client_session.h"
|
||||||
|
@ -14,15 +15,17 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
static SharedPtr<Object> MakeObject() {
|
static SharedPtr<Object> MakeObject(Kernel::KernelSystem& kernel) {
|
||||||
return Event::Create(ResetType::OneShot);
|
return kernel.CreateEvent(ResetType::OneShot);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") {
|
TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") {
|
||||||
auto session = std::get<SharedPtr<ServerSession>>(ServerSession::CreateSessionPair());
|
CoreTiming::Init();
|
||||||
|
Kernel::KernelSystem kernel(0);
|
||||||
|
auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair());
|
||||||
HLERequestContext context(std::move(session));
|
HLERequestContext context(std::move(session));
|
||||||
|
|
||||||
auto process = Process::Create(CodeSet::Create("", 0));
|
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
|
||||||
HandleTable handle_table;
|
HandleTable handle_table;
|
||||||
|
|
||||||
SECTION("works with empty cmdbuf") {
|
SECTION("works with empty cmdbuf") {
|
||||||
|
@ -52,7 +55,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("translates move handles") {
|
SECTION("translates move handles") {
|
||||||
auto a = MakeObject();
|
auto a = MakeObject(kernel);
|
||||||
Handle a_handle = handle_table.Create(a).Unwrap();
|
Handle a_handle = handle_table.Create(a).Unwrap();
|
||||||
const u32_le input[]{
|
const u32_le input[]{
|
||||||
IPC::MakeHeader(0, 0, 2),
|
IPC::MakeHeader(0, 0, 2),
|
||||||
|
@ -68,7 +71,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("translates copy handles") {
|
SECTION("translates copy handles") {
|
||||||
auto a = MakeObject();
|
auto a = MakeObject(kernel);
|
||||||
Handle a_handle = handle_table.Create(a).Unwrap();
|
Handle a_handle = handle_table.Create(a).Unwrap();
|
||||||
const u32_le input[]{
|
const u32_le input[]{
|
||||||
IPC::MakeHeader(0, 0, 2),
|
IPC::MakeHeader(0, 0, 2),
|
||||||
|
@ -84,9 +87,9 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("translates multi-handle descriptors") {
|
SECTION("translates multi-handle descriptors") {
|
||||||
auto a = MakeObject();
|
auto a = MakeObject(kernel);
|
||||||
auto b = MakeObject();
|
auto b = MakeObject(kernel);
|
||||||
auto c = MakeObject();
|
auto c = MakeObject(kernel);
|
||||||
const u32_le input[]{
|
const u32_le input[]{
|
||||||
IPC::MakeHeader(0, 0, 5), IPC::MoveHandleDesc(2),
|
IPC::MakeHeader(0, 0, 5), IPC::MoveHandleDesc(2),
|
||||||
handle_table.Create(a).Unwrap(), handle_table.Create(b).Unwrap(),
|
handle_table.Create(a).Unwrap(), handle_table.Create(b).Unwrap(),
|
||||||
|
@ -190,7 +193,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
||||||
buffer_mapped->size(), MemoryState::Private);
|
buffer_mapped->size(), MemoryState::Private);
|
||||||
REQUIRE(result.Code() == RESULT_SUCCESS);
|
REQUIRE(result.Code() == RESULT_SUCCESS);
|
||||||
|
|
||||||
auto a = MakeObject();
|
auto a = MakeObject(kernel);
|
||||||
const u32_le input[]{
|
const u32_le input[]{
|
||||||
IPC::MakeHeader(0, 2, 8),
|
IPC::MakeHeader(0, 2, 8),
|
||||||
0x12345678,
|
0x12345678,
|
||||||
|
@ -222,13 +225,17 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
||||||
REQUIRE(process->vm_manager.UnmapRange(target_address_mapped, buffer_mapped->size()) ==
|
REQUIRE(process->vm_manager.UnmapRange(target_address_mapped, buffer_mapped->size()) ==
|
||||||
RESULT_SUCCESS);
|
RESULT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CoreTiming::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
||||||
auto session = std::get<SharedPtr<ServerSession>>(ServerSession::CreateSessionPair());
|
CoreTiming::Init();
|
||||||
|
Kernel::KernelSystem kernel(0);
|
||||||
|
auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair());
|
||||||
HLERequestContext context(std::move(session));
|
HLERequestContext context(std::move(session));
|
||||||
|
|
||||||
auto process = Process::Create(CodeSet::Create("", 0));
|
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
|
||||||
HandleTable handle_table;
|
HandleTable handle_table;
|
||||||
auto* input = context.CommandBuffer();
|
auto* input = context.CommandBuffer();
|
||||||
u32_le output[IPC::COMMAND_BUFFER_LENGTH];
|
u32_le output[IPC::COMMAND_BUFFER_LENGTH];
|
||||||
|
@ -255,8 +262,8 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("translates move/copy handles") {
|
SECTION("translates move/copy handles") {
|
||||||
auto a = MakeObject();
|
auto a = MakeObject(kernel);
|
||||||
auto b = MakeObject();
|
auto b = MakeObject(kernel);
|
||||||
input[0] = IPC::MakeHeader(0, 0, 4);
|
input[0] = IPC::MakeHeader(0, 0, 4);
|
||||||
input[1] = IPC::MoveHandleDesc(1);
|
input[1] = IPC::MoveHandleDesc(1);
|
||||||
input[2] = context.AddOutgoingHandle(a);
|
input[2] = context.AddOutgoingHandle(a);
|
||||||
|
@ -281,9 +288,9 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("translates multi-handle descriptors") {
|
SECTION("translates multi-handle descriptors") {
|
||||||
auto a = MakeObject();
|
auto a = MakeObject(kernel);
|
||||||
auto b = MakeObject();
|
auto b = MakeObject(kernel);
|
||||||
auto c = MakeObject();
|
auto c = MakeObject(kernel);
|
||||||
input[0] = IPC::MakeHeader(0, 0, 5);
|
input[0] = IPC::MakeHeader(0, 0, 5);
|
||||||
input[1] = IPC::MoveHandleDesc(2);
|
input[1] = IPC::MoveHandleDesc(2);
|
||||||
input[2] = context.AddOutgoingHandle(a);
|
input[2] = context.AddOutgoingHandle(a);
|
||||||
|
@ -361,6 +368,8 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
||||||
REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer->size()) ==
|
REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer->size()) ==
|
||||||
RESULT_SUCCESS);
|
RESULT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CoreTiming::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -3,14 +3,17 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <catch2/catch.hpp>
|
#include <catch2/catch.hpp>
|
||||||
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/kernel/memory.h"
|
#include "core/hle/kernel/memory.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
#include "core/hle/shared_page.h"
|
#include "core/hle/shared_page.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") {
|
TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") {
|
||||||
|
CoreTiming::Init();
|
||||||
|
Kernel::KernelSystem kernel(0);
|
||||||
SECTION("these regions should not be mapped on an empty process") {
|
SECTION("these regions should not be mapped on an empty process") {
|
||||||
auto process = Kernel::Process::Create(Kernel::CodeSet::Create("", 0));
|
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
|
||||||
CHECK(Memory::IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false);
|
||||||
CHECK(Memory::IsValidVirtualAddress(*process, Memory::HEAP_VADDR) == false);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::HEAP_VADDR) == false);
|
||||||
CHECK(Memory::IsValidVirtualAddress(*process, Memory::LINEAR_HEAP_VADDR) == false);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::LINEAR_HEAP_VADDR) == false);
|
||||||
|
@ -21,14 +24,14 @@ TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") {
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("CONFIG_MEMORY_VADDR and SHARED_PAGE_VADDR should be valid after mapping them") {
|
SECTION("CONFIG_MEMORY_VADDR and SHARED_PAGE_VADDR should be valid after mapping them") {
|
||||||
auto process = Kernel::Process::Create(Kernel::CodeSet::Create("", 0));
|
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
|
||||||
Kernel::MapSharedPages(process->vm_manager);
|
Kernel::MapSharedPages(process->vm_manager);
|
||||||
CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == true);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == true);
|
||||||
CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == true);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("special regions should be valid after mapping them") {
|
SECTION("special regions should be valid after mapping them") {
|
||||||
auto process = Kernel::Process::Create(Kernel::CodeSet::Create("", 0));
|
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
|
||||||
SECTION("VRAM") {
|
SECTION("VRAM") {
|
||||||
Kernel::HandleSpecialMapping(process->vm_manager,
|
Kernel::HandleSpecialMapping(process->vm_manager,
|
||||||
{Memory::VRAM_VADDR, Memory::VRAM_SIZE, false, false});
|
{Memory::VRAM_VADDR, Memory::VRAM_SIZE, false, false});
|
||||||
|
@ -43,9 +46,11 @@ TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") {
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Unmapping a VAddr should make it invalid") {
|
SECTION("Unmapping a VAddr should make it invalid") {
|
||||||
auto process = Kernel::Process::Create(Kernel::CodeSet::Create("", 0));
|
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
|
||||||
Kernel::MapSharedPages(process->vm_manager);
|
Kernel::MapSharedPages(process->vm_manager);
|
||||||
process->vm_manager.UnmapRange(Memory::CONFIG_MEMORY_VADDR, Memory::CONFIG_MEMORY_SIZE);
|
process->vm_manager.UnmapRange(Memory::CONFIG_MEMORY_VADDR, Memory::CONFIG_MEMORY_SIZE);
|
||||||
CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
|
CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CoreTiming::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue