diff --git a/src/core/hle/service/sm/sm_controller.cpp b/src/core/hle/service/sm/sm_controller.cpp index 7f0fb91d0..384fc752f 100644 --- a/src/core/hle/service/sm/sm_controller.cpp +++ b/src/core/hle/service/sm/sm_controller.cpp @@ -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(0x10000)); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(0x8000); + rb.Push(static_cast(final_size)); } // https://switchbrew.org/wiki/IPC_Marshalling