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
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/alignment.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/kernel/k_client_port.h"
|
#include "core/hle/kernel/k_client_port.h"
|
||||||
@@ -68,11 +69,57 @@ void Controller::CloneCurrentObjectEx(HLERequestContext& ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Controller::QueryPointerBufferSize(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};
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.Push<u16>(0x8000);
|
rb.Push<u16>(static_cast<u16>(final_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://switchbrew.org/wiki/IPC_Marshalling
|
// https://switchbrew.org/wiki/IPC_Marshalling
|
||||||
|
|||||||
Reference in New Issue
Block a user