blob: 0fef6a20e91a40384aab742c82b8bc23df6fa287 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "msd_img_connection.h"
#include "gtest/gtest.h"
#include "include/fuchsia_communication.h"
#include "msd_img_buffer.h"
#include "pvr_bridge.h"
namespace
{
class FakeOwner : public MsdImgConnection::Owner
{
PVRSRV_DEVICE_NODE* device_node() override { return nullptr; }
};
} // namespace
class TestMsdImgConnection
{
public:
static void ProcessBuffer()
{
FakeOwner owner;
MsdImgConnection connection(&owner, 1);
constexpr uint32_t kBufferSize = 4096;
auto cmd_buf = MsdImgAbiBuffer(MsdImgBuffer::Create(kBufferSize, "cmd-buf"));
auto payload_buf = MsdImgAbiBuffer(MsdImgBuffer::Create(kBufferSize, "payload"));
auto additional_buf = MsdImgAbiBuffer(MsdImgBuffer::Create(kBufferSize, "array"));
void* mapped_cpu_addr;
ASSERT_TRUE(cmd_buf.base_ptr()->platform_buffer()->MapCpu(&mapped_cpu_addr));
auto system_buf = reinterpret_cast<magma_system_command_buffer*>(mapped_cpu_addr);
msd_buffer_t* exec_resources[3] = { &payload_buf, &additional_buf };
PVRSRV_BRIDGE_PACKAGE package;
// Need at least 1 resource
system_buf->num_resources = 0;
EXPECT_EQ(MAGMA_STATUS_INVALID_ARGS, connection.ProcessCommandBuffer(&cmd_buf, exec_resources, &package));
EXPECT_FALSE(connection.payload_buffer_);
system_buf->num_resources = 1;
ASSERT_TRUE(payload_buf.base_ptr()->platform_buffer()->MapCpu(&mapped_cpu_addr));
auto payload_buf_data = reinterpret_cast<FuchsiaImgCommandPayload*>(mapped_cpu_addr);
constexpr uint32_t kValidDataSize = kBufferSize - sizeof(*payload_buf_data);
// in_data_size is larger than payload buffer.
payload_buf_data->in_data_size = kValidDataSize + 1;
EXPECT_EQ(MAGMA_STATUS_INVALID_ARGS, connection.ProcessCommandBuffer(&cmd_buf, exec_resources, &package));
EXPECT_FALSE(connection.payload_buffer_);
// in_data_size is way larger than payload buffer and could cause overflow.
payload_buf_data->in_data_size = 0xffffffff;
EXPECT_EQ(MAGMA_STATUS_INVALID_ARGS, connection.ProcessCommandBuffer(&cmd_buf, exec_resources, &package));
EXPECT_FALSE(connection.payload_buffer_);
constexpr uint64_t kThreadId = 0x8765432187654321ul;
payload_buf_data->thread_id = kThreadId;
payload_buf_data->bridge_group = 1;
payload_buf_data->function_id = 2;
payload_buf_data->in_data_size = kValidDataSize;
payload_buf_data->out_data_size = kValidDataSize;
EXPECT_EQ(MAGMA_STATUS_OK, connection.ProcessCommandBuffer(&cmd_buf, exec_resources, &package));
EXPECT_EQ(kThreadId, connection.current_client_thread_id_);
EXPECT_EQ(1u, package.ui32BridgeID);
EXPECT_EQ(2u, package.ui32FunctionID);
EXPECT_EQ(sizeof(package), package.ui32Size);
EXPECT_EQ(kValidDataSize, package.ui32InBufferSize);
EXPECT_EQ(kValidDataSize, package.ui32OutBufferSize);
EXPECT_EQ(payload_buf_data + 1, package.pvParamIn);
EXPECT_EQ(payload_buf_data + 1, package.pvParamOut);
EXPECT_EQ(payload_buf.base_ptr(), connection.payload_buffer_);
EXPECT_EQ(nullptr, connection.TakeAdditionalBuffer());
// Unmap to test whether the buffer was mapped persistently.
ASSERT_TRUE(payload_buf.base_ptr()->platform_buffer()->UnmapCpu());
connection.payload_buffer_ = nullptr;
// 2 resources are given, so the last should be used as the
// additional buffer.
system_buf->num_resources = 2;
EXPECT_EQ(MAGMA_STATUS_OK, connection.ProcessCommandBuffer(&cmd_buf, exec_resources, &package));
EXPECT_EQ(additional_buf.base_ptr(), connection.TakeAdditionalBuffer());
EXPECT_EQ(nullptr, connection.TakeAdditionalBuffer());
// The parameters should be at the same address because the
// buffer has a persistent mapping.
EXPECT_EQ(payload_buf_data + 1, package.pvParamIn);
}
};
TEST(Connection, ProcessBuffer) { TestMsdImgConnection::ProcessBuffer(); }