citra/src/core/hle/kernel/kernel.h

280 lines
9.5 KiB
C++
Raw Normal View History

2014-05-10 03:11:18 +01:00
// Copyright 2014 Citra Emulator Project / PPSSPP Project
2014-12-17 05:38:14 +00:00
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
2014-05-10 03:11:18 +01:00
#pragma once
#include <array>
#include <atomic>
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
2015-05-06 08:06:12 +01:00
#include "common/common_types.h"
#include "core/hle/kernel/memory.h"
2018-10-12 20:47:06 +01:00
#include "core/hle/result.h"
#include "core/memory.h"
2014-05-10 03:11:18 +01:00
namespace ConfigMem {
class Handler;
}
namespace SharedPage {
class Handler;
}
2018-11-21 03:48:19 +00:00
namespace Memory {
class MemorySystem;
}
namespace Core {
class Timing;
}
namespace Kernel {
class AddressArbiter;
2018-10-11 20:48:16 +01:00
class Event;
2018-10-11 21:00:09 +01:00
class Mutex;
2018-10-12 20:21:32 +01:00
class CodeSet;
2018-10-12 20:33:36 +01:00
class Process;
2018-10-12 20:47:06 +01:00
class Thread;
2018-10-12 21:12:08 +01:00
class Semaphore;
2018-10-12 21:26:23 +01:00
class Timer;
2018-10-13 00:00:16 +01:00
class ClientPort;
class ServerPort;
2018-10-13 21:11:20 +01:00
class ClientSession;
class ServerSession;
class ResourceLimitList;
2018-10-13 22:08:37 +01:00
class SharedMemory;
2018-10-23 14:57:59 +01:00
class ThreadManager;
class TimerManager;
class VMManager;
struct AddressMapping;
2018-10-11 20:48:16 +01:00
enum class ResetType {
OneShot,
Sticky,
Pulse,
};
2018-10-13 22:08:37 +01:00
/// 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,
};
2018-10-11 19:49:52 +01:00
class KernelSystem {
public:
explicit KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing,
std::function<void()> prepare_reschedule_callback, u32 system_mode);
2018-10-11 19:49:52 +01:00
~KernelSystem();
using PortPair = std::pair<std::shared_ptr<ServerPort>, std::shared_ptr<ClientPort>>;
using SessionPair = std::pair<std::shared_ptr<ServerSession>, std::shared_ptr<ClientSession>>;
/**
* Creates an address arbiter.
*
* @param name Optional name used for debugging.
* @returns The created AddressArbiter.
*/
std::shared_ptr<AddressArbiter> CreateAddressArbiter(std::string name = "Unknown");
2018-10-11 20:48:16 +01:00
/**
* Creates an event
* @param reset_type ResetType describing how to create event
* @param name Optional name of event
*/
std::shared_ptr<Event> CreateEvent(ResetType reset_type, std::string name = "Unknown");
2018-10-11 21:00:09 +01:00
/**
* 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
*/
std::shared_ptr<Mutex> CreateMutex(bool initial_locked, std::string name = "Unknown");
2018-10-12 20:21:32 +01:00
std::shared_ptr<CodeSet> CreateCodeSet(std::string name, u64 program_id);
2018-10-12 20:33:36 +01:00
std::shared_ptr<Process> CreateProcess(std::shared_ptr<CodeSet> code_set);
2018-10-12 20:47:06 +01:00
/**
* 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<std::shared_ptr<Thread>> CreateThread(std::string name, VAddr entry_point,
u32 priority, u32 arg, s32 processor_id,
VAddr stack_top, Process& owner_process);
2018-10-12 21:12:08 +01:00
/**
* 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<std::shared_ptr<Semaphore>> CreateSemaphore(s32 initial_count, s32 max_count,
std::string name = "Unknown");
2018-10-12 21:26:23 +01:00
/**
* Creates a timer
* @param reset_type ResetType describing how to create the timer
* @param name Optional name of timer
* @return The created Timer
*/
std::shared_ptr<Timer> CreateTimer(ResetType reset_type, std::string name = "Unknown");
2018-10-13 00:00:16 +01:00
/**
* 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
*/
PortPair CreatePortPair(u32 max_sessions, std::string name = "UnknownPort");
2018-10-13 21:11:20 +01:00
/**
* 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
*/
SessionPair CreateSessionPair(const std::string& name = "Unknown",
std::shared_ptr<ClientPort> client_port = nullptr);
ResourceLimitList& ResourceLimit();
const ResourceLimitList& ResourceLimit() const;
2018-10-13 22:08:37 +01:00
/**
* 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.
*/
ResultVal<std::shared_ptr<SharedMemory>> CreateSharedMemory(
Process* owner_process, u32 size, MemoryPermission permissions,
MemoryPermission other_permissions, VAddr address = 0,
MemoryRegion region = MemoryRegion::BASE, std::string name = "Unknown");
2018-10-13 22:08:37 +01:00
/**
* Creates a shared memory object from a block of memory managed by an 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.
*/
std::shared_ptr<SharedMemory> CreateSharedMemoryForApplet(u32 offset, u32 size,
MemoryPermission permissions,
MemoryPermission other_permissions,
std::string name = "Unknown Applet");
2018-10-13 22:08:37 +01:00
u32 GenerateObjectID();
/// Retrieves a process from the current list of processes.
std::shared_ptr<Process> GetProcessById(u32 process_id) const;
std::shared_ptr<Process> GetCurrentProcess() const;
void SetCurrentProcess(std::shared_ptr<Process> process);
void SetCurrentMemPageTable(Memory::PageTable* page_table);
void SetCPU(std::shared_ptr<ARM_Interface> cpu);
2018-10-23 14:57:59 +01:00
ThreadManager& GetThreadManager();
const ThreadManager& GetThreadManager() const;
TimerManager& GetTimerManager();
const TimerManager& GetTimerManager() const;
void MapSharedPages(VMManager& address_space);
SharedPage::Handler& GetSharedPageHandler();
const SharedPage::Handler& GetSharedPageHandler() const;
MemoryRegionInfo* GetMemoryRegion(MemoryRegion region);
void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping);
std::array<MemoryRegionInfo, 3> memory_regions;
/// Adds a port to the named port table
void AddNamedPort(std::string name, std::shared_ptr<ClientPort> port);
void PrepareReschedule() {
prepare_reschedule_callback();
}
/// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort
std::unordered_map<std::string, std::shared_ptr<ClientPort>> named_ports;
std::shared_ptr<ARM_Interface> current_cpu;
2018-11-21 03:48:19 +00:00
Memory::MemorySystem& memory;
Core::Timing& timing;
private:
void MemoryInit(u32 mem_type);
std::function<void()> prepare_reschedule_callback;
std::unique_ptr<ResourceLimitList> resource_limits;
std::atomic<u32> next_object_id{0};
// Note: keep the member order below in order to perform correct destruction.
// Thread manager is destructed before process list in order to Stop threads and clear thread
// info from their parent processes first. Timer manager is destructed after process list
// because timers are destructed along with process list and they need to clear info from the
// timer manager.
// TODO (wwylele): refactor the cleanup sequence to make this less complicated and sensitive.
std::unique_ptr<TimerManager> timer_manager;
// TODO(Subv): Start the process ids from 10 for now, as lower PIDs are
// reserved for low-level services
u32 next_process_id = 10;
// Lists all processes that exist in the current session.
std::vector<std::shared_ptr<Process>> process_list;
std::shared_ptr<Process> current_process;
2018-10-23 14:57:59 +01:00
std::unique_ptr<ThreadManager> thread_manager;
std::unique_ptr<ConfigMem::Handler> config_mem_handler;
std::unique_ptr<SharedPage::Handler> shared_page_handler;
2018-10-11 19:49:52 +01:00
};
} // namespace Kernel