| // 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(); } |