early-access version 1591
This commit is contained in:
@@ -75,14 +75,10 @@ void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_
|
||||
if (incoming) {
|
||||
// Populate the object lists with the data in the IPC request.
|
||||
for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) {
|
||||
const u32 copy_handle{rp.Pop<Handle>()};
|
||||
copy_handles.push_back(copy_handle);
|
||||
copy_objects.push_back(handle_table.GetGeneric(copy_handle));
|
||||
copy_objects.push_back(handle_table.GetGeneric(rp.Pop<Handle>()));
|
||||
}
|
||||
for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_move; ++handle) {
|
||||
const u32 move_handle{rp.Pop<Handle>()};
|
||||
move_handles.push_back(move_handle);
|
||||
move_objects.push_back(handle_table.GetGeneric(move_handle));
|
||||
move_objects.push_back(handle_table.GetGeneric(rp.Pop<Handle>()));
|
||||
}
|
||||
} else {
|
||||
// For responses we just ignore the handles, they're empty and will be populated when
|
||||
|
@@ -210,14 +210,6 @@ public:
|
||||
/// Helper function to test whether the output buffer at buffer_index can be written
|
||||
bool CanWriteBuffer(std::size_t buffer_index = 0) const;
|
||||
|
||||
Handle GetCopyHandle(std::size_t index) const {
|
||||
return copy_handles.at(index);
|
||||
}
|
||||
|
||||
Handle GetMoveHandle(std::size_t index) const {
|
||||
return move_handles.at(index);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<T> GetCopyObject(std::size_t index) {
|
||||
return DynamicObjectCast<T>(copy_objects.at(index));
|
||||
@@ -293,8 +285,6 @@ private:
|
||||
std::shared_ptr<Kernel::ServerSession> server_session;
|
||||
std::shared_ptr<KThread> thread;
|
||||
// TODO(yuriks): Check common usage of this and optimize size accordingly
|
||||
boost::container::small_vector<Handle, 8> move_handles;
|
||||
boost::container::small_vector<Handle, 8> copy_handles;
|
||||
boost::container::small_vector<std::shared_ptr<Object>, 8> move_objects;
|
||||
boost::container::small_vector<std::shared_ptr<Object>, 8> copy_objects;
|
||||
boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;
|
||||
|
@@ -402,7 +402,7 @@ public:
|
||||
return wait_cancelled;
|
||||
}
|
||||
|
||||
[[nodiscard]] void ClearWaitCancelled() {
|
||||
void ClearWaitCancelled() {
|
||||
wait_cancelled = false;
|
||||
}
|
||||
|
||||
|
@@ -67,13 +67,8 @@ struct KernelCore::Impl {
|
||||
is_phantom_mode_for_singlecore = false;
|
||||
|
||||
InitializePhysicalCores();
|
||||
|
||||
// Derive the initial memory layout from the emulated board
|
||||
KMemoryLayout memory_layout;
|
||||
DeriveInitialMemoryLayout(memory_layout);
|
||||
InitializeMemoryLayout(memory_layout);
|
||||
InitializeSystemResourceLimit(kernel, system, memory_layout);
|
||||
InitializeSlabHeaps();
|
||||
InitializeSystemResourceLimit(kernel, system);
|
||||
InitializeMemoryLayout();
|
||||
InitializeSchedulers();
|
||||
InitializeSuspendThreads();
|
||||
InitializePreemption(kernel);
|
||||
@@ -142,32 +137,27 @@ struct KernelCore::Impl {
|
||||
}
|
||||
|
||||
// Creates the default system resource limit
|
||||
void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system,
|
||||
const KMemoryLayout& memory_layout) {
|
||||
void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system) {
|
||||
system_resource_limit = std::make_shared<KResourceLimit>(kernel, system);
|
||||
const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes();
|
||||
|
||||
// If setting the default system values fails, then something seriously wrong has occurred.
|
||||
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, total_size)
|
||||
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, 0x100000000)
|
||||
.IsSuccess());
|
||||
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess());
|
||||
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 900).IsSuccess());
|
||||
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200)
|
||||
.IsSuccess());
|
||||
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 1133).IsSuccess());
|
||||
system_resource_limit->Reserve(LimitableResource::PhysicalMemory, kernel_size);
|
||||
|
||||
// Derived from recent software updates. The kernel reserves 27MB
|
||||
constexpr u64 kernel_size{0x1b00000};
|
||||
if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemory, kernel_size)) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
// Reserve secure applet memory, introduced in firmware 5.0.0
|
||||
constexpr u64 secure_applet_memory_size{Common::Size_4_MB};
|
||||
constexpr u64 secure_applet_memory_size{0x400000};
|
||||
ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory,
|
||||
secure_applet_memory_size));
|
||||
|
||||
// This memory seems to be reserved on hardware, but is not reserved/used by yuzu.
|
||||
// Likely Horizon OS reserved memory
|
||||
// TODO(ameerj): Derive the memory rather than hardcode it.
|
||||
constexpr u64 unknown_reserved_memory{0x2f896000};
|
||||
ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory,
|
||||
unknown_reserved_memory));
|
||||
}
|
||||
|
||||
void InitializePreemption(KernelCore& kernel) {
|
||||
@@ -541,7 +531,11 @@ struct KernelCore::Impl {
|
||||
linear_region_start);
|
||||
}
|
||||
|
||||
void InitializeMemoryLayout(const KMemoryLayout& memory_layout) {
|
||||
void InitializeMemoryLayout() {
|
||||
// Derive the initial memory layout from the emulated board
|
||||
KMemoryLayout memory_layout;
|
||||
DeriveInitialMemoryLayout(memory_layout);
|
||||
|
||||
const auto system_pool = memory_layout.GetKernelSystemPoolRegionPhysicalExtents();
|
||||
const auto applet_pool = memory_layout.GetKernelAppletPoolRegionPhysicalExtents();
|
||||
const auto application_pool = memory_layout.GetKernelApplicationPoolRegionPhysicalExtents();
|
||||
@@ -584,14 +578,11 @@ struct KernelCore::Impl {
|
||||
system.Kernel(), system.DeviceMemory(), nullptr, {time_phys_addr, time_size / PageSize},
|
||||
KMemoryPermission::None, KMemoryPermission::Read, time_phys_addr, time_size,
|
||||
"Time:SharedMemory");
|
||||
}
|
||||
|
||||
void InitializeSlabHeaps() {
|
||||
// Allocate slab heaps
|
||||
user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>();
|
||||
|
||||
// TODO(ameerj): This should be derived, not hardcoded within the kernel
|
||||
constexpr u64 user_slab_heap_size{0x3de000};
|
||||
constexpr u64 user_slab_heap_size{0x1ef000};
|
||||
// Reserve slab heaps
|
||||
ASSERT(
|
||||
system_resource_limit->Reserve(LimitableResource::PhysicalMemory, user_slab_heap_size));
|
||||
|
@@ -120,7 +120,9 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name,
|
||||
std::shared_ptr<Process> process = std::make_shared<Process>(system);
|
||||
process->name = std::move(name);
|
||||
|
||||
process->resource_limit = kernel.GetSystemResourceLimit();
|
||||
// TODO: This is inaccurate
|
||||
// The process should hold a reference to the kernel-wide resource limit.
|
||||
process->resource_limit = std::make_shared<KResourceLimit>(kernel, system);
|
||||
process->status = ProcessStatus::Created;
|
||||
process->program_id = 0;
|
||||
process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID()
|
||||
@@ -158,6 +160,9 @@ void Process::DecrementThreadCount() {
|
||||
}
|
||||
|
||||
u64 Process::GetTotalPhysicalMemoryAvailable() const {
|
||||
// TODO: This is expected to always return the application memory pool size after accurately
|
||||
// reserving kernel resources. The current workaround uses a process-local resource limit of
|
||||
// application memory pool size, which is inaccurate.
|
||||
const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) +
|
||||
page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size +
|
||||
main_thread_stack_size};
|
||||
@@ -165,6 +170,7 @@ u64 Process::GetTotalPhysicalMemoryAvailable() const {
|
||||
if (capacity < memory_usage_capacity) {
|
||||
return capacity;
|
||||
}
|
||||
|
||||
return memory_usage_capacity;
|
||||
}
|
||||
|
||||
@@ -266,6 +272,10 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
|
||||
system_resource_size = metadata.GetSystemResourceSize();
|
||||
image_size = code_size;
|
||||
|
||||
// Set initial resource limits
|
||||
resource_limit->SetLimitValue(
|
||||
LimitableResource::PhysicalMemory,
|
||||
kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application));
|
||||
KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory,
|
||||
code_size + system_resource_size);
|
||||
if (!memory_reservation.Succeeded()) {
|
||||
@@ -314,6 +324,16 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
// Set initial resource limits
|
||||
resource_limit->SetLimitValue(
|
||||
LimitableResource::PhysicalMemory,
|
||||
kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application));
|
||||
|
||||
resource_limit->SetLimitValue(LimitableResource::Threads, 608);
|
||||
resource_limit->SetLimitValue(LimitableResource::Events, 700);
|
||||
resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128);
|
||||
resource_limit->SetLimitValue(LimitableResource::Sessions, 894);
|
||||
|
||||
// Create TLS region
|
||||
tls_region_address = CreateTLSRegion();
|
||||
memory_reservation.Commit();
|
||||
|
Reference in New Issue
Block a user