aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/handle_table.cpp3
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp67
-rw-r--r--src/core/hle/kernel/hle_ipc.h34
-rw-r--r--src/core/hle/kernel/kernel.cpp1
-rw-r--r--src/core/hle/kernel/kernel.h4
-rw-r--r--src/core/hle/kernel/object_address_table.cpp4
-rw-r--r--src/core/hle/kernel/process.cpp27
-rw-r--r--src/core/hle/kernel/process.h8
-rw-r--r--src/core/hle/kernel/scheduler.cpp7
-rw-r--r--src/core/hle/kernel/server_session.cpp8
-rw-r--r--src/core/hle/kernel/shared_memory.cpp18
-rw-r--r--src/core/hle/kernel/svc.cpp68
-rw-r--r--src/core/hle/kernel/svc_wrap.h15
-rw-r--r--src/core/hle/kernel/thread.cpp33
-rw-r--r--src/core/hle/kernel/thread.h2
-rw-r--r--src/core/hle/kernel/vm_manager.cpp42
-rw-r--r--src/core/hle/kernel/vm_manager.h38
-rw-r--r--src/core/hle/kernel/wait_object.cpp3
18 files changed, 232 insertions, 150 deletions
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp
index 3beb55753..822449cd5 100644
--- a/src/core/hle/kernel/handle_table.cpp
+++ b/src/core/hle/kernel/handle_table.cpp
@@ -5,6 +5,7 @@
#include <utility>
#include "common/assert.h"
#include "common/logging/log.h"
+#include "core/core.h"
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"
@@ -77,7 +78,7 @@ SharedPtr<Object> HandleTable::GetGeneric(Handle handle) const {
if (handle == CurrentThread) {
return GetCurrentThread();
} else if (handle == CurrentProcess) {
- return g_current_process;
+ return Core::CurrentProcess();
}
if (!IsValid(handle)) {
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 25ba26f18..bef4f15f5 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -7,6 +7,7 @@
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/event.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/kernel.h"
@@ -26,6 +27,32 @@ void SessionRequestHandler::ClientDisconnected(SharedPtr<ServerSession> server_s
boost::range::remove_erase(connected_sessions, server_session);
}
+SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
+ const std::string& reason, u64 timeout,
+ WakeupCallback&& callback) {
+
+ // Put the client thread to sleep until the wait event is signaled or the timeout expires.
+ thread->wakeup_callback =
+ [context = *this, callback](ThreadWakeupReason reason, SharedPtr<Thread> thread,
+ SharedPtr<WaitObject> object, size_t index) mutable -> bool {
+ ASSERT(thread->status == THREADSTATUS_WAIT_HLE_EVENT);
+ callback(thread, context, reason);
+ context.WriteToOutgoingCommandBuffer(*thread);
+ return true;
+ };
+
+ auto event = Kernel::Event::Create(Kernel::ResetType::OneShot, "HLE Pause Event: " + reason);
+ thread->status = THREADSTATUS_WAIT_HLE_EVENT;
+ thread->wait_objects = {event};
+ event->AddWaitingThread(thread);
+
+ if (timeout > 0) {
+ thread->WakeAfterDelay(timeout);
+ }
+
+ return event;
+}
+
HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session)
: server_session(std::move(server_session)) {
cmd_buf[0] = 0;
@@ -35,7 +62,7 @@ HLERequestContext::~HLERequestContext() = default;
void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
IPC::RequestParser rp(src_cmdbuf);
- command_header = std::make_unique<IPC::CommandHeader>(rp.PopRaw<IPC::CommandHeader>());
+ command_header = std::make_shared<IPC::CommandHeader>(rp.PopRaw<IPC::CommandHeader>());
if (command_header->type == IPC::CommandType::Close) {
// Close does not populate the rest of the IPC header
@@ -45,7 +72,7 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
// If handle descriptor is present, add size of it
if (command_header->enable_handle_descriptor) {
handle_descriptor_header =
- std::make_unique<IPC::HandleDescriptorHeader>(rp.PopRaw<IPC::HandleDescriptorHeader>());
+ std::make_shared<IPC::HandleDescriptorHeader>(rp.PopRaw<IPC::HandleDescriptorHeader>());
if (handle_descriptor_header->send_current_pid) {
rp.Skip(2, false);
}
@@ -85,13 +112,18 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
if (Session()->IsDomain() && (command_header->type == IPC::CommandType::Request || !incoming)) {
// If this is an incoming message, only CommandType "Request" has a domain header
- // All outgoing domain messages have the domain header
- domain_message_header =
- std::make_unique<IPC::DomainMessageHeader>(rp.PopRaw<IPC::DomainMessageHeader>());
+ // All outgoing domain messages have the domain header, if only incoming has it
+ if (incoming || domain_message_header) {
+ domain_message_header =
+ std::make_shared<IPC::DomainMessageHeader>(rp.PopRaw<IPC::DomainMessageHeader>());
+ } else {
+ if (Session()->IsDomain())
+ LOG_WARNING(IPC, "Domain request has no DomainMessageHeader!");
+ }
}
data_payload_header =
- std::make_unique<IPC::DataPayloadHeader>(rp.PopRaw<IPC::DataPayloadHeader>());
+ std::make_shared<IPC::DataPayloadHeader>(rp.PopRaw<IPC::DataPayloadHeader>());
data_payload_offset = rp.GetCurrentOffset();
@@ -154,8 +186,11 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(u32_le* src_cmdb
return RESULT_SUCCESS;
}
-ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process,
- HandleTable& dst_table) {
+ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) {
+ std::array<u32, IPC::COMMAND_BUFFER_LENGTH> dst_cmdbuf;
+ Memory::ReadBlock(*thread.owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(),
+ dst_cmdbuf.size() * sizeof(u32));
+
// The header was already built in the internal command buffer. Attempt to parse it to verify
// the integrity and then copy it over to the target command buffer.
ParseCommandBuffer(cmd_buf.data(), false);
@@ -166,7 +201,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P
if (domain_message_header)
size -= sizeof(IPC::DomainMessageHeader) / sizeof(u32);
- std::copy_n(cmd_buf.begin(), size, dst_cmdbuf);
+ std::copy_n(cmd_buf.begin(), size, dst_cmdbuf.data());
if (command_header->enable_handle_descriptor) {
ASSERT_MSG(!move_objects.empty() || !copy_objects.empty(),
@@ -196,7 +231,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P
// TODO(Subv): Translate the X/A/B/W buffers.
- if (Session()->IsDomain()) {
+ if (Session()->IsDomain() && domain_message_header) {
ASSERT(domain_message_header->num_objects == domain_objects.size());
// Write the domain objects to the command buffer, these go after the raw untranslated data.
// TODO(Subv): This completely ignores C buffers.
@@ -208,6 +243,11 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P
dst_cmdbuf[domain_offset++] = static_cast<u32_le>(request_handlers.size());
}
}
+
+ // Copy the translated command buffer back into the thread's command buffer area.
+ Memory::WriteBlock(*thread.owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(),
+ dst_cmdbuf.size() * sizeof(u32));
+
return RESULT_SUCCESS;
}
@@ -228,8 +268,11 @@ std::vector<u8> HLERequestContext::ReadBuffer() const {
size_t HLERequestContext::WriteBuffer(const void* buffer, size_t size) const {
const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[0].Size()};
-
- ASSERT_MSG(size <= GetWriteBufferSize(), "Size %d is too big", size);
+ const size_t buffer_size{GetWriteBufferSize()};
+ if (size > buffer_size) {
+ LOG_CRITICAL(Core, "size (%016zx) is greater than buffer_size (%016zx)", size, buffer_size);
+ size = buffer_size; // TODO(bunnei): This needs to be HW tested
+ }
if (is_buffer_b) {
Memory::WriteBlock(BufferDescriptorB()[0].Address(), buffer, size);
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index b5631b773..8b35da4c9 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -6,6 +6,7 @@
#include <array>
#include <memory>
+#include <string>
#include <vector>
#include <boost/container/small_vector.hpp>
#include "common/common_types.h"
@@ -13,6 +14,7 @@
#include "core/hle/ipc.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/server_session.h"
+#include "core/hle/kernel/thread.h"
namespace Service {
class ServiceFrameworkBase;
@@ -24,6 +26,7 @@ class Domain;
class HandleTable;
class HLERequestContext;
class Process;
+class Event;
/**
* Interface implemented by HLE Session handlers.
@@ -102,14 +105,31 @@ public:
return server_session;
}
+ using WakeupCallback = std::function<void(SharedPtr<Thread> thread, HLERequestContext& context,
+ ThreadWakeupReason reason)>;
+
+ /**
+ * Puts the specified guest thread to sleep until the returned event is signaled or until the
+ * specified timeout expires.
+ * @param thread Thread to be put to sleep.
+ * @param reason Reason for pausing the thread, to be used for debugging purposes.
+ * @param timeout Timeout in nanoseconds after which the thread will be awoken and the callback
+ * invoked with a Timeout reason.
+ * @param callback Callback to be invoked when the thread is resumed. This callback must write
+ * the entire command response once again, regardless of the state of it before this function
+ * was called.
+ * @returns Event that when signaled will resume the thread and call the callback function.
+ */
+ SharedPtr<Event> SleepClientThread(SharedPtr<Thread> thread, const std::string& reason,
+ u64 timeout, WakeupCallback&& callback);
+
void ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming);
/// Populates this context with data from the requesting process/thread.
ResultCode PopulateFromIncomingCommandBuffer(u32_le* src_cmdbuf, Process& src_process,
HandleTable& src_table);
/// Writes data from this context back to the requesting process/thread.
- ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process,
- HandleTable& dst_table);
+ ResultCode WriteToOutgoingCommandBuffer(Thread& thread);
u32_le GetCommand() const {
return command;
@@ -139,7 +159,7 @@ public:
return buffer_c_desciptors;
}
- const std::unique_ptr<IPC::DomainMessageHeader>& GetDomainMessageHeader() const {
+ const std::shared_ptr<IPC::DomainMessageHeader>& GetDomainMessageHeader() const {
return domain_message_header;
}
@@ -212,10 +232,10 @@ private:
boost::container::small_vector<SharedPtr<Object>, 8> copy_objects;
boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;
- std::unique_ptr<IPC::CommandHeader> command_header;
- std::unique_ptr<IPC::HandleDescriptorHeader> handle_descriptor_header;
- std::unique_ptr<IPC::DataPayloadHeader> data_payload_header;
- std::unique_ptr<IPC::DomainMessageHeader> domain_message_header;
+ std::shared_ptr<IPC::CommandHeader> command_header;
+ std::shared_ptr<IPC::HandleDescriptorHeader> handle_descriptor_header;
+ std::shared_ptr<IPC::DataPayloadHeader> data_payload_header;
+ std::shared_ptr<IPC::DomainMessageHeader> domain_message_header;
std::vector<IPC::BufferDescriptorX> buffer_x_desciptors;
std::vector<IPC::BufferDescriptorABW> buffer_a_desciptors;
std::vector<IPC::BufferDescriptorABW> buffer_b_desciptors;
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index b0c3f4ae1..b325b879b 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -41,7 +41,6 @@ void Shutdown() {
g_object_address_table.Clear();
Kernel::ThreadingShutdown();
- g_current_process = nullptr;
Kernel::TimersShutdown();
Kernel::ResourceLimitsShutdown();
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index c77e58f3c..053bf4e17 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -33,10 +33,6 @@ enum class HandleType : u32 {
ServerSession,
};
-enum {
- DEFAULT_STACK_SIZE = 0x10000,
-};
-
enum class ResetType {
OneShot,
Sticky,
diff --git a/src/core/hle/kernel/object_address_table.cpp b/src/core/hle/kernel/object_address_table.cpp
index 434c16add..cd286f85d 100644
--- a/src/core/hle/kernel/object_address_table.cpp
+++ b/src/core/hle/kernel/object_address_table.cpp
@@ -10,12 +10,12 @@ namespace Kernel {
ObjectAddressTable g_object_address_table;
void ObjectAddressTable::Insert(VAddr addr, SharedPtr<Object> obj) {
- ASSERT_MSG(objects.find(addr) == objects.end(), "Object already exists with addr=0x%llx", addr);
+ ASSERT_MSG(objects.find(addr) == objects.end(), "Object already exists with addr=0x%lx", addr);
objects[addr] = obj;
}
void ObjectAddressTable::Close(VAddr addr) {
- ASSERT_MSG(objects.find(addr) != objects.end(), "Object does not exist with addr=0x%llx", addr);
+ ASSERT_MSG(objects.find(addr) != objects.end(), "Object does not exist with addr=0x%lx", addr);
objects.erase(addr);
}
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 8e74059ea..2cffec198 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -20,12 +20,9 @@ namespace Kernel {
// Lists all processes that exist in the current session.
static std::vector<SharedPtr<Process>> process_list;
-SharedPtr<CodeSet> CodeSet::Create(std::string name, u64 program_id) {
+SharedPtr<CodeSet> CodeSet::Create(std::string name) {
SharedPtr<CodeSet> codeset(new CodeSet);
-
codeset->name = std::move(name);
- codeset->program_id = program_id;
-
return codeset;
}
@@ -41,6 +38,7 @@ SharedPtr<Process> Process::Create(std::string&& name) {
process->flags.raw = 0;
process->flags.memory_region.Assign(MemoryRegion::APPLICATION);
process->status = ProcessStatus::Created;
+ process->program_id = 0;
process_list.push_back(process);
return process;
@@ -119,11 +117,13 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
}
void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
- // Allocate and map stack
+ // Allocate and map the main thread stack
+ // TODO(bunnei): This is heap area that should be allocated by the kernel and not mapped as part
+ // of the user address space.
vm_manager
- .MapMemoryBlock(Memory::HEAP_VADDR_END - stack_size,
+ .MapMemoryBlock(Memory::STACK_AREA_VADDR_END - stack_size,
std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size,
- MemoryState::Heap)
+ MemoryState::Mapped)
.Unwrap();
misc_memory_used += stack_size;
memory_region->used += stack_size;
@@ -155,9 +155,9 @@ void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {
};
// Map CodeSet segments
- MapSegment(module_->code, VMAPermission::ReadExecute, MemoryState::Code);
- MapSegment(module_->rodata, VMAPermission::Read, MemoryState::Static);
- MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::Static);
+ MapSegment(module_->code, VMAPermission::ReadExecute, MemoryState::CodeStatic);
+ MapSegment(module_->rodata, VMAPermission::Read, MemoryState::CodeMutable);
+ MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::CodeMutable);
}
VAddr Process::GetLinearHeapAreaAddress() const {
@@ -184,6 +184,8 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per
// Initialize heap
heap_memory = std::make_shared<std::vector<u8>>();
heap_start = heap_end = target;
+ } else {
+ vm_manager.UnmapRange(heap_start, heap_end - heap_start);
}
// If necessary, expand backing vector to cover new heap extents.
@@ -203,7 +205,7 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per
size, MemoryState::Heap));
vm_manager.Reprotect(vma, perms);
- heap_used += size;
+ heap_used = size;
memory_region->used += size;
return MakeResult<VAddr>(heap_end - size);
@@ -290,7 +292,7 @@ ResultCode Process::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
CASCADE_RESULT(auto new_vma,
vm_manager.MapMemoryBlock(dst_addr, backing_block, backing_block_offset, size,
- vma->second.meminfo_state));
+ MemoryState::Mapped));
// Protect mirror with permissions from old region
vm_manager.Reprotect(new_vma, vma->second.permissions);
// Remove permissions from old region
@@ -321,5 +323,4 @@ SharedPtr<Process> GetProcessById(u32 process_id) {
return *itr;
}
-SharedPtr<Process> g_current_process;
} // namespace Kernel
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index add98472f..68e77a4d1 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -56,7 +56,7 @@ class ResourceLimit;
struct MemoryRegionInfo;
struct CodeSet final : public Object {
- static SharedPtr<CodeSet> Create(std::string name, u64 program_id);
+ static SharedPtr<CodeSet> Create(std::string name);
std::string GetTypeName() const override {
return "CodeSet";
@@ -72,8 +72,6 @@ struct CodeSet final : public Object {
/// Name of the process
std::string name;
- /// Title ID corresponding to the process
- u64 program_id;
std::shared_ptr<std::vector<u8>> memory;
@@ -113,6 +111,9 @@ public:
static u32 next_process_id;
+ /// Title ID corresponding to the process
+ u64 program_id;
+
/// Resource limit descriptor for this process
SharedPtr<ResourceLimit> resource_limit;
@@ -202,5 +203,4 @@ void ClearProcessList();
/// Retrieves a process from the current list of processes.
SharedPtr<Process> GetProcessById(u32 process_id);
-extern SharedPtr<Process> g_current_process;
} // namespace Kernel
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index 235068b22..921f27efb 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/scheduler.h"
@@ -67,7 +68,7 @@ void Scheduler::SwitchContext(Thread* new_thread) {
// Cancel any outstanding wakeup events for this thread
new_thread->CancelWakeupTimer();
- auto previous_process = Kernel::g_current_process;
+ auto previous_process = Core::CurrentProcess();
current_thread = new_thread;
@@ -75,8 +76,8 @@ void Scheduler::SwitchContext(Thread* new_thread) {
new_thread->status = THREADSTATUS_RUNNING;
if (previous_process != current_thread->owner_process) {
- Kernel::g_current_process = current_thread->owner_process;
- SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table);
+ Core::CurrentProcess() = current_thread->owner_process;
+ SetCurrentPageTable(&Core::CurrentProcess()->vm_manager.page_table);
}
cpu_core->LoadContext(new_thread->context);
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp
index 5608418c3..33397d84f 100644
--- a/src/core/hle/kernel/server_session.cpp
+++ b/src/core/hle/kernel/server_session.cpp
@@ -4,6 +4,7 @@
#include <tuple>
+#include "core/core.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/client_session.h"
@@ -77,7 +78,8 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con
}
}
- LOG_CRITICAL(IPC, "Unknown domain command=%d", domain_message_header->command.Value());
+ LOG_CRITICAL(IPC, "Unknown domain command=%d",
+ static_cast<int>(domain_message_header->command.Value()));
ASSERT(false);
}
@@ -91,12 +93,12 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
Kernel::HLERequestContext context(this);
u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress());
- context.PopulateFromIncomingCommandBuffer(cmd_buf, *Kernel::g_current_process,
+ context.PopulateFromIncomingCommandBuffer(cmd_buf, *Core::CurrentProcess(),
Kernel::g_handle_table);
ResultCode result = RESULT_SUCCESS;
// If the session has been converted to a domain, handle the domain request
- if (IsDomain()) {
+ if (IsDomain() && context.GetDomainMessageHeader()) {
result = HandleDomainSyncRequest(context);
// If there is no domain header, the regular session handler is used
} else if (hle_handler != nullptr) {
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index d4505061e..88230bdd9 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -4,6 +4,7 @@
#include <cstring>
#include "common/logging/log.h"
+#include "core/core.h"
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/shared_memory.h"
@@ -51,8 +52,8 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
}
// Refresh the address mappings for the current process.
- if (Kernel::g_current_process != nullptr) {
- Kernel::g_current_process->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
+ if (Core::CurrentProcess() != nullptr) {
+ Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
}
} else {
auto& vm_manager = shared_memory->owner_process->vm_manager;
@@ -106,7 +107,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
// Error out if the requested permissions don't match what the creator process allows.
if (static_cast<u32>(permissions) & ~static_cast<u32>(own_other_permissions)) {
- LOG_ERROR(Kernel, "cannot map id=%u, address=0x%llx name=%s, permissions don't match",
+ LOG_ERROR(Kernel, "cannot map id=%u, address=0x%lx name=%s, permissions don't match",
GetObjectId(), address, name.c_str());
return ERR_INVALID_COMBINATION;
}
@@ -114,7 +115,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
// Error out if the provided permissions are not compatible with what the creator process needs.
if (other_permissions != MemoryPermission::DontCare &&
static_cast<u32>(this->permissions) & ~static_cast<u32>(other_permissions)) {
- LOG_ERROR(Kernel, "cannot map id=%u, address=0x%llx name=%s, permissions don't match",
+ LOG_ERROR(Kernel, "cannot map id=%u, address=0x%lx name=%s, permissions don't match",
GetObjectId(), address, name.c_str());
return ERR_WRONG_PERMISSION;
}
@@ -125,7 +126,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
if (address != 0) {
// TODO(shinyquagsire23): Check for virtual/mappable memory here too?
if (address >= Memory::HEAP_VADDR && address < Memory::HEAP_VADDR_END) {
- LOG_ERROR(Kernel, "cannot map id=%u, address=0x%llx name=%s, invalid address",
+ LOG_ERROR(Kernel, "cannot map id=%u, address=0x%lx name=%s, invalid address",
GetObjectId(), address, name.c_str());
return ERR_INVALID_ADDRESS;
}
@@ -142,10 +143,9 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
auto result = target_process->vm_manager.MapMemoryBlock(
target_address, backing_block, backing_block_offset, size, MemoryState::Shared);
if (result.Failed()) {
- LOG_ERROR(
- Kernel,
- "cannot map id=%u, target_address=0x%llx name=%s, error mapping to virtual memory",
- GetObjectId(), target_address, name.c_str());
+ LOG_ERROR(Kernel,
+ "cannot map id=%u, target_address=0x%lx name=%s, error mapping to virtual memory",
+ GetObjectId(), target_address, name.c_str());
return result.Code();
}
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 1ab8cbd88..171bbd956 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -8,6 +8,7 @@
#include "common/logging/log.h"
#include "common/microprofile.h"
#include "common/string_util.h"
+#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/client_session.h"
@@ -31,14 +32,14 @@ namespace Kernel {
/// Set the process heap to a given Size. It can both extend and shrink the heap.
static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
LOG_TRACE(Kernel_SVC, "called, heap_size=0x%llx", heap_size);
- auto& process = *g_current_process;
+ auto& process = *Core::CurrentProcess();
CASCADE_RESULT(*heap_addr,
process.HeapAllocate(Memory::HEAP_VADDR, heap_size, VMAPermission::ReadWrite));
return RESULT_SUCCESS;
}
static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) {
- LOG_WARNING(Kernel_SVC, "(STUBBED) called, addr=0x%llx", addr);
+ LOG_WARNING(Kernel_SVC, "(STUBBED) called, addr=0x%lx", addr);
return RESULT_SUCCESS;
}
@@ -46,14 +47,14 @@ static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state
static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr,
src_addr, size);
- return g_current_process->MirrorMemory(dst_addr, src_addr, size);
+ return Core::CurrentProcess()->MirrorMemory(dst_addr, src_addr, size);
}
/// Unmaps a region that was previously mapped with svcMapMemory
static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr,
src_addr, size);
- return g_current_process->UnmapMemory(dst_addr, src_addr, size);
+ return Core::CurrentProcess()->UnmapMemory(dst_addr, src_addr, size);
}
/// Connect to an OS service given the port name, returns the handle to the port to out
@@ -306,23 +307,23 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
LOG_TRACE(Kernel_SVC, "called info_id=0x%X, info_sub_id=0x%X, handle=0x%08X", info_id,
info_sub_id, handle);
- auto& vm_manager = g_current_process->vm_manager;
+ auto& vm_manager = Core::CurrentProcess()->vm_manager;
switch (static_cast<GetInfoType>(info_id)) {
case GetInfoType::AllowedCpuIdBitmask:
- *result = g_current_process->allowed_processor_mask;
+ *result = Core::CurrentProcess()->allowed_processor_mask;
break;
case GetInfoType::AllowedThreadPrioBitmask:
- *result = g_current_process->allowed_thread_priority_mask;
+ *result = Core::CurrentProcess()->allowed_thread_priority_mask;
break;
case GetInfoType::MapRegionBaseAddr:
- *result = vm_manager.GetMapRegionBaseAddr();
+ *result = Memory::MAP_REGION_VADDR;
break;
case GetInfoType::MapRegionSize:
- *result = vm_manager.GetAddressSpaceSize();
+ *result = Memory::MAP_REGION_SIZE;
break;
case GetInfoType::HeapRegionBaseAddr:
- *result = vm_manager.GetNewMapRegionBaseAddr() + vm_manager.GetNewMapRegionSize();
+ *result = Memory::HEAP_VADDR;
break;
case GetInfoType::HeapRegionSize:
*result = Memory::HEAP_SIZE;
@@ -346,13 +347,13 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
*result = vm_manager.GetAddressSpaceSize();
break;
case GetInfoType::NewMapRegionBaseAddr:
- *result = vm_manager.GetNewMapRegionBaseAddr();
+ *result = Memory::NEW_MAP_REGION_VADDR;
break;
case GetInfoType::NewMapRegionSize:
- *result = vm_manager.GetNewMapRegionSize();
+ *result = Memory::NEW_MAP_REGION_SIZE;
break;
case GetInfoType::IsVirtualAddressMemoryEnabled:
- *result = g_current_process->is_virtual_address_memory_enabled;
+ *result = Core::CurrentProcess()->is_virtual_address_memory_enabled;
break;
case GetInfoType::TitleId:
LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0");
@@ -392,7 +393,7 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
// Note: The kernel uses the current process's resource limit instead of
// the one from the thread owner's resource limit.
- SharedPtr<ResourceLimit>& resource_limit = g_current_process->resource_limit;
+ SharedPtr<ResourceLimit>& resource_limit = Core::CurrentProcess()->resource_limit;
if (resource_limit->GetMaxResourceValue(ResourceTypes::PRIORITY) > priority) {
return ERR_NOT_AUTHORIZED;
}
@@ -435,7 +436,7 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
case MemoryPermission::WriteExecute:
case MemoryPermission::ReadWriteExecute:
case MemoryPermission::DontCare:
- return shared_memory->Map(g_current_process.get(), addr, permissions_type,
+ return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type,
MemoryPermission::DontCare);
default:
LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions);
@@ -451,7 +452,7 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64
SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle);
- return shared_memory->Unmap(g_current_process.get(), addr);
+ return shared_memory->Unmap(Core::CurrentProcess().get(), addr);
}
/// Query process memory
@@ -463,11 +464,11 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i
}
auto vma = process->vm_manager.FindVMA(addr);
memory_info->attributes = 0;
- if (vma == g_current_process->vm_manager.vma_map.end()) {
+ if (vma == Core::CurrentProcess()->vm_manager.vma_map.end()) {
memory_info->base_address = 0;
memory_info->permission = static_cast<u32>(VMAPermission::None);
memory_info->size = 0;
- memory_info->type = static_cast<u32>(MemoryState::Free);
+ memory_info->type = static_cast<u32>(MemoryState::Unmapped);
} else {
memory_info->base_address = vma->second.base;
memory_info->permission = static_cast<u32>(vma->second.permissions);
@@ -487,16 +488,17 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAdd
/// Exits the current process
static void ExitProcess() {
- LOG_INFO(Kernel_SVC, "Process %u exiting", g_current_process->process_id);
+ LOG_INFO(Kernel_SVC, "Process %u exiting", Core::CurrentProcess()->process_id);
- ASSERT_MSG(g_current_process->status == ProcessStatus::Running, "Process has already exited");
+ ASSERT_MSG(Core::CurrentProcess()->status == ProcessStatus::Running,
+ "Process has already exited");
- g_current_process->status = ProcessStatus::Exited;
+ Core::CurrentProcess()->status = ProcessStatus::Exited;
// Stop all the process threads that are currently waiting for objects.
auto& thread_list = Core::System::GetInstance().Scheduler().GetThreadList();
for (auto& thread : thread_list) {
- if (thread->owner_process != g_current_process)
+ if (thread->owner_process != Core::CurrentProcess())
continue;
if (thread == GetCurrentThread())
@@ -525,14 +527,14 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
return ERR_OUT_OF_RANGE;
}
- SharedPtr<ResourceLimit>& resource_limit = g_current_process->resource_limit;
+ SharedPtr<ResourceLimit>& resource_limit = Core::CurrentProcess()->resource_limit;
if (resource_limit->GetMaxResourceValue(ResourceTypes::PRIORITY) > priority) {
return ERR_NOT_AUTHORIZED;
}
if (processor_id == THREADPROCESSORID_DEFAULT) {
// Set the target CPU to the one specified in the process' exheader.
- processor_id = g_current_process->ideal_processor;
+ processor_id = Core::CurrentProcess()->ideal_processor;
ASSERT(processor_id != THREADPROCESSORID_DEFAULT);
}
@@ -554,7 +556,7 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
CASCADE_RESULT(SharedPtr<Thread> thread,
Thread::Create(name, entry_point, priority, arg, processor_id, stack_top,
- g_current_process));
+ Core::CurrentProcess()));
CASCADE_RESULT(thread->guest_handle, g_handle_table.Create(thread));
*out_handle = thread->guest_handle;
@@ -748,14 +750,22 @@ static ResultCode ResetSignal(Handle handle) {
/// Creates a TransferMemory object
static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32 permissions) {
- LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%llx, size=0x%llx, perms=%08X", addr, size,
+ LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%lx, size=0x%lx, perms=%08X", addr, size,
permissions);
*handle = 0;
return RESULT_SUCCESS;
}
-static ResultCode SetThreadCoreMask(u64, u64, u64) {
- LOG_WARNING(Kernel_SVC, "(STUBBED) called");
+static ResultCode GetThreadCoreMask(Handle handle, u32* mask, u64* unknown) {
+ LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X", handle);
+ *mask = 0x0;
+ *unknown = 0xf;
+ return RESULT_SUCCESS;
+}
+
+static ResultCode SetThreadCoreMask(Handle handle, u32 mask, u64 unknown) {
+ LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X, mask=0x%08X, unknown=0x%lx", handle,
+ mask, unknown);
return RESULT_SUCCESS;
}
@@ -807,7 +817,7 @@ static const FunctionDef SVC_Table[] = {
{0x0B, SvcWrap<SleepThread>, "SleepThread"},
{0x0C, SvcWrap<GetThreadPriority>, "GetThreadPriority"},
{0x0D, SvcWrap<SetThreadPriority>, "SetThreadPriority"},
- {0x0E, nullptr, "GetThreadCoreMask"},
+ {0x0E, SvcWrap<GetThreadCoreMask>, "GetThreadCoreMask"},
{0x0F, SvcWrap<SetThreadCoreMask>, "SetThreadCoreMask"},
{0x10, SvcWrap<GetCurrentProcessorNumber>, "GetCurrentProcessorNumber"},
{0x11, nullptr, "SignalEvent"},
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h
index b224f5e67..5da4f5269 100644
--- a/src/core/hle/kernel/svc_wrap.h
+++ b/src/core/hle/kernel/svc_wrap.h
@@ -70,6 +70,21 @@ void SvcWrap() {
FuncReturn(retval);
}
+template <ResultCode func(u32, u32, u64)>
+void SvcWrap() {
+ FuncReturn(func((u32)(PARAM(0) & 0xFFFFFFFF), (u32)(PARAM(1) & 0xFFFFFFFF), PARAM(2)).raw);
+}
+
+template <ResultCode func(u32, u32*, u64*)>
+void SvcWrap() {
+ u32 param_1 = 0;
+ u64 param_2 = 0;
+ ResultCode retval = func((u32)(PARAM(2) & 0xFFFFFFFF), &param_1, &param_2);
+ Core::CPU().SetReg(1, param_1);
+ Core::CPU().SetReg(2, param_2);
+ FuncReturn(retval.raw);
+}
+
template <ResultCode func(u64, u64, u32, u32)>
void SvcWrap() {
FuncReturn(
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index dd0a8ae48..f3a8aa4aa 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -55,16 +55,6 @@ inline static u32 const NewThreadId() {
Thread::Thread() {}
Thread::~Thread() {}
-/**
- * Check if the specified thread is waiting on the specified address to be arbitrated
- * @param thread The thread to test
- * @param wait_address The address to test against
- * @return True if the thread is waiting, false otherwise
- */
-static bool CheckWait_AddressArbiter(const Thread* thread, VAddr wait_address) {
- return thread->status == THREADSTATUS_WAIT_ARB && wait_address == thread->wait_address;
-}
-
void Thread::Stop() {
// Cancel any outstanding wakeup events for this thread
CoreTiming::UnscheduleEvent(ThreadWakeupEventType, callback_handle);
@@ -94,7 +84,7 @@ void Thread::Stop() {
u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE;
u64 tls_slot =
((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE;
- Kernel::g_current_process->tls_slots[tls_page].reset(tls_slot);
+ Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot);
}
void WaitCurrentThread_Sleep() {
@@ -102,12 +92,6 @@ void WaitCurrentThread_Sleep() {
thread->status = THREADSTATUS_WAIT_SLEEP;
}
-void WaitCurrentThread_ArbitrateAddress(VAddr wait_address) {
- Thread* thread = GetCurrentThread();
- thread->wait_address = wait_address;
- thread->status = THREADSTATUS_WAIT_ARB;
-}
-
void ExitCurrentThread() {
Thread* thread = GetCurrentThread();
thread->Stop();
@@ -129,7 +113,8 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
bool resume = true;
if (thread->status == THREADSTATUS_WAIT_SYNCH_ANY ||
- thread->status == THREADSTATUS_WAIT_SYNCH_ALL || thread->status == THREADSTATUS_WAIT_ARB) {
+ thread->status == THREADSTATUS_WAIT_SYNCH_ALL ||
+ thread->status == THREADSTATUS_WAIT_HLE_EVENT) {
// Remove the thread from each of its waiting objects' waitlists
for (auto& object : thread->wait_objects)
@@ -163,7 +148,7 @@ void Thread::ResumeFromWait() {
switch (status) {
case THREADSTATUS_WAIT_SYNCH_ALL:
case THREADSTATUS_WAIT_SYNCH_ANY:
- case THREADSTATUS_WAIT_ARB:
+ case THREADSTATUS_WAIT_HLE_EVENT:
case THREADSTATUS_WAIT_SLEEP:
case THREADSTATUS_WAIT_IPC:
break;
@@ -314,7 +299,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
// TODO(Subv): Find the correct MemoryState for this region.
vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE,
linheap_memory, offset, Memory::PAGE_SIZE,
- MemoryState::ThreadLocalStorage);
+ MemoryState::ThreadLocal);
}
// Mark the slot as used
@@ -353,11 +338,11 @@ void Thread::BoostPriority(u32 priority) {
SharedPtr<Thread> SetupMainThread(VAddr entry_point, u32 priority,
SharedPtr<Process> owner_process) {
// Setup page table so we can write to memory
- SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table);
+ SetCurrentPageTable(&Core::CurrentProcess()->vm_manager.page_table);
// Initialize new "main" thread
auto thread_res = Thread::Create("main", entry_point, priority, 0, THREADPROCESSORID_0,
- Memory::HEAP_VADDR_END, owner_process);
+ Memory::STACK_AREA_VADDR_END, owner_process);
SharedPtr<Thread> thread = std::move(thread_res).Unwrap();
@@ -406,6 +391,8 @@ void ThreadingInit() {
next_thread_id = 1;
}
-void ThreadingShutdown() {}
+void ThreadingShutdown() {
+ Kernel::ClearProcessList();
+}
} // namespace Kernel
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 4fd2fc2f8..dbf47e269 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -38,7 +38,7 @@ enum ThreadProcessorId : s32 {
enum ThreadStatus {
THREADSTATUS_RUNNING, ///< Currently running
THREADSTATUS_READY, ///< Ready to run
- THREADSTATUS_WAIT_ARB, ///< Waiting on an address arbiter
+ THREADSTATUS_WAIT_HLE_EVENT, ///< Waiting for hle event to finish
THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC
THREADSTATUS_WAIT_IPC, ///< Waiting for the reply from an IPC request
THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp
index d5b36d71a..1c2f873aa 100644
--- a/src/core/hle/kernel/vm_manager.cpp
+++ b/src/core/hle/kernel/vm_manager.cpp
@@ -18,8 +18,26 @@ namespace Kernel {
static const char* GetMemoryStateName(MemoryState state) {
static const char* names[] = {
- "Free", "Reserved", "IO", "Static", "Code", "Private",
- "Shared", "Continuous", "Aliased", "Alias", "AliasCode", "Locked",
+ "Unmapped",
+ "Io",
+ "Normal",
+ "CodeStatic",
+ "CodeMutable",
+ "Heap",
+ "Shared",
+ "Unknown1"
+ "ModuleCodeStatic",
+ "ModuleCodeMutable",
+ "IpcBuffer0",
+ "Mapped",
+ "ThreadLocal",
+ "TransferMemoryIsolated",
+ "TransferMemory",
+ "ProcessMemory",
+ "Unknown2"
+ "IpcBuffer1",
+ "IpcBuffer3",
+ "KernelStack",
};
return names[(int)state];
@@ -142,7 +160,7 @@ VMManager::VMAIter VMManager::Unmap(VMAIter vma_handle) {
VirtualMemoryArea& vma = vma_handle->second;
vma.type = VMAType::Free;
vma.permissions = VMAPermission::None;
- vma.meminfo_state = MemoryState::Free;
+ vma.meminfo_state = MemoryState::Unmapped;
vma.backing_block = nullptr;
vma.offset = 0;
@@ -166,6 +184,9 @@ ResultCode VMManager::UnmapRange(VAddr target, u64 size) {
}
ASSERT(FindVMA(target)->second.size >= size);
+
+ Core::CPU().UnmapMemory(target, size);
+
return RESULT_SUCCESS;
}
@@ -377,19 +398,4 @@ u64 VMManager::GetAddressSpaceSize() {
return MAX_ADDRESS;
}
-VAddr VMManager::GetMapRegionBaseAddr() {
- LOG_WARNING(Kernel, "(STUBBED) called");
- return Memory::HEAP_VADDR;
-}
-
-VAddr VMManager::GetNewMapRegionBaseAddr() {
- LOG_WARNING(Kernel, "(STUBBED) called");
- return 0x8000000;
-}
-
-u64 VMManager::GetNewMapRegionSize() {
- LOG_WARNING(Kernel, "(STUBBED) called");
- return 0x8000000;
-}
-
} // namespace Kernel
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h
index 8de704a60..4d66146f6 100644
--- a/src/core/hle/kernel/vm_manager.h
+++ b/src/core/hle/kernel/vm_manager.h
@@ -41,15 +41,24 @@ enum class VMAPermission : u8 {
/// Set of values returned in MemoryInfo.state by svcQueryMemory.
enum class MemoryState : u32 {
- Free = 0,
- IO = 1,
- Normal = 2,
- Code = 3,
- Static = 4,
- Heap = 5,
- Shared = 6,
- Mapped = 6,
- ThreadLocalStorage = 12,
+ Unmapped = 0x0,
+ Io = 0x1,
+ Normal = 0x2,
+ CodeStatic = 0x3,
+ CodeMutable = 0x4,
+ Heap = 0x5,
+ Shared = 0x6,
+ ModuleCodeStatic = 0x8,
+ ModuleCodeMutable = 0x9,
+ IpcBuffer0 = 0xA,
+ Mapped = 0xB,
+ ThreadLocal = 0xC,
+ TransferMemoryIsolated = 0xD,
+ TransferMemory = 0xE,
+ ProcessMemory = 0xF,
+ IpcBuffer1 = 0x11,
+ IpcBuffer3 = 0x12,
+ KernelStack = 0x13,
};
/**
@@ -66,7 +75,7 @@ struct VirtualMemoryArea {
VMAType type = VMAType::Free;
VMAPermission permissions = VMAPermission::None;
/// Tag returned by svcQueryMemory. Not otherwise used.
- MemoryState meminfo_state = MemoryState::Free;
+ MemoryState meminfo_state = MemoryState::Unmapped;
// Settings for type = AllocatedMemoryBlock
/// Memory block backing this VMA.
@@ -192,15 +201,6 @@ public:
/// Gets the total address space address size, used by svcGetInfo
u64 GetAddressSpaceSize();
- /// Gets the map region base address, used by svcGetInfo
- VAddr GetMapRegionBaseAddr();
-
- /// Gets the base address for a new memory region, used by svcGetInfo
- VAddr GetNewMapRegionBaseAddr();
-
- /// Gets the size for a new memory region, used by svcGetInfo
- u64 GetNewMapRegionSize();
-
/// Each VMManager has its own page table, which is set as the main one when the owning process
/// is scheduled.
Memory::PageTable page_table;
diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp
index ec147b84c..b08ac72c1 100644
--- a/src/core/hle/kernel/wait_object.cpp
+++ b/src/core/hle/kernel/wait_object.cpp
@@ -39,7 +39,8 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
for (const auto& thread : waiting_threads) {
// The list of waiting threads must not contain threads that are not waiting to be awakened.
ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY ||
- thread->status == THREADSTATUS_WAIT_SYNCH_ALL,
+ thread->status == THREADSTATUS_WAIT_SYNCH_ALL ||
+ thread->status == THREADSTATUS_WAIT_HLE_EVENT,
"Inconsistent thread statuses in waiting_threads");
if (thread->current_priority >= candidate_priority)