mirror of
https://git.citron-emu.org/citron/emulator
synced 2025-12-21 11:33:35 +00:00
Merge branch 'implement-query-pointer-buffer-size' into 'master'
service: Implement QueryPointerBufferSize with proper IPC buffer calculation See merge request citron/rewrite!52
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/alignment.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/k_client_port.h"
|
||||
@@ -68,11 +69,57 @@ void Controller::CloneCurrentObjectEx(HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void Controller::QueryPointerBufferSize(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
LOG_DEBUG(Service, "called");
|
||||
|
||||
// The pointer buffer size is determined by the system's IPC message buffer requirements.
|
||||
// Based on the IPC structures and message buffer implementations, the pointer buffer
|
||||
// needs to accommodate various buffer descriptors and message headers.
|
||||
//
|
||||
// The size should be sufficient for:
|
||||
// - Multiple buffer descriptors (X, A, B, W, C types)
|
||||
// - Message headers and handle descriptors
|
||||
// - Data payload headers
|
||||
// - Domain message headers
|
||||
// - Pointer descriptors for IPC marshalling
|
||||
|
||||
// Calculate the required size based on IPC message buffer requirements
|
||||
constexpr u32 base_message_buffer_size = 0x100; // 256 bytes base message buffer
|
||||
constexpr u32 max_buffer_descriptors = 4; // Maximum descriptors per type
|
||||
constexpr u32 descriptor_sizes[] = {
|
||||
8, // BufferDescriptorX
|
||||
12, // BufferDescriptorABW
|
||||
8, // BufferDescriptorC
|
||||
8, // PointerDescriptor
|
||||
16, // DomainMessageHeader
|
||||
8, // DataPayloadHeader
|
||||
4, // HandleDescriptorHeader
|
||||
};
|
||||
|
||||
// Calculate total descriptor space needed
|
||||
u32 total_descriptor_size = 0;
|
||||
for (u32 size : descriptor_sizes) {
|
||||
total_descriptor_size += size * max_buffer_descriptors;
|
||||
}
|
||||
|
||||
// Add overhead for alignment and message headers
|
||||
constexpr u32 alignment_overhead = 16;
|
||||
constexpr u32 message_header_size = 8;
|
||||
|
||||
// Calculate final pointer buffer size
|
||||
const u32 pointer_buffer_size = base_message_buffer_size +
|
||||
total_descriptor_size +
|
||||
alignment_overhead +
|
||||
message_header_size;
|
||||
|
||||
// Ensure the size is aligned to a reasonable boundary (4KB)
|
||||
const u32 aligned_size = Common::AlignUp(pointer_buffer_size, 0x1000);
|
||||
|
||||
// Cap the size to a reasonable maximum (64KB) to prevent excessive memory usage
|
||||
const u32 final_size = std::min(aligned_size, static_cast<u32>(0x10000));
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<u16>(0x8000);
|
||||
rb.Push<u16>(static_cast<u16>(final_size));
|
||||
}
|
||||
|
||||
// https://switchbrew.org/wiki/IPC_Marshalling
|
||||
|
||||
Reference in New Issue
Block a user