// Copyright 2021 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 <cpuid.h>
#include <fidl/fuchsia.kernel/cpp/wire.h>
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fdio.h>
#include <lib/zircon-internal/device/cpu-trace/intel-pm.h>
#include <lib/zircon-internal/mtrace.h>
#include <lib/zx/channel.h>
#include <lib/zx/resource.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

#include <zxtest/zxtest.h>

namespace {

zx::result<zx::resource> GetDebugResource() {
  zx::result<fidl::ClientEnd<fuchsia_kernel::DebugResource>> client_end =
      component::Connect<fuchsia_kernel::DebugResource>();
  if (client_end.is_error()) {
    printf("mtrace: Could not connect to DebugResource service: %s\n", client_end.status_string());
    return zx::error(client_end.error_value());
  }

  fidl::WireSyncClient<fuchsia_kernel::DebugResource> client =
      fidl::WireSyncClient(std::move(client_end.value()));
  fidl::WireResult<fuchsia_kernel::DebugResource::Get> result = client->Get();
  if (result.status() != ZX_OK) {
    printf("mtrace: Could not retrieve DebugResource: %s\n", zx_status_get_string(result.status()));
    return zx::error(result.status());
  }
  return zx::ok(std::move(result->resource));
}

std::optional<uint8_t> IntelArchitecturalPMUVersion() {
  uint32_t eax, ebx, ecx, edx;
  if (__get_cpuid_count(0xa, 0, &eax, &ebx, &ecx, &edx) == 1) {
    return eax & 0xf;
  }
  return std::nullopt;
}

bool IsIntelPMUSupported() {
  std::optional<uint8_t> version = IntelArchitecturalPMUVersion();
  if (version) {
    return *version >= MTRACE_X86_INTEL_PMU_MIN_SUPPORTED_VERSION &&
           *version <= MTRACE_X86_INTEL_PMU_MAX_SUPPORTED_VERSION;
  }
  return false;
}

TEST(X86MtraceTestCase, GetProperties) {
  perfmon::X86PmuProperties properties;
  zx::result<zx::resource> debug_resource_or_error = GetDebugResource();
  zx::resource debug_resource = std::move(debug_resource_or_error.value());
  ASSERT_TRUE(debug_resource_or_error.is_ok(), "failed to get debug resource: %s",
              zx_status_get_string(debug_resource_or_error.error_value()));
  zx_status_t status =
      zx_mtrace_control(debug_resource.get(), MTRACE_KIND_PERFMON, MTRACE_PERFMON_GET_PROPERTIES, 0,
                        &properties, sizeof(properties));
  if (IsIntelPMUSupported()) {
    EXPECT_EQ(status, ZX_OK);
    EXPECT_EQ(properties.common.pm_version, IntelArchitecturalPMUVersion());
  } else {
    printf("Skipping test, Intel Architectual PMU not supported\n");
    EXPECT_EQ(status, ZX_ERR_NOT_SUPPORTED);
  }
}

// MTRACE_KIND_PERFMON expects MTRACE_PERFMON_INIT to be called before any performance tracing
// session and MTRACE_PERFMON_FINI to be called after any session. Check that they can be called.
//
// Note that MTRACE_KIND_PERFMON is currently single-master; only a single agent needs to or can
// invoke MTRACE_PERFMON_INIT / MTRACE_PERFMON_FINI at a time.
TEST(X86MtraceTestCase, InitFini) {
  zx::result<zx::resource> debug_resource_or_error = GetDebugResource();
  ASSERT_TRUE(debug_resource_or_error.is_ok(), "failed to get debug resource: %s",
              zx_status_get_string(debug_resource_or_error.error_value()));
  zx::resource debug_resource = std::move(debug_resource_or_error.value());

  zx_status_t status = zx_mtrace_control(debug_resource.get(), MTRACE_KIND_PERFMON,
                                         MTRACE_PERFMON_INIT, 0, nullptr, 0);
  if (!IsIntelPMUSupported()) {
    EXPECT_EQ(status, ZX_ERR_NOT_SUPPORTED);
    printf("Skipping test, Intel Architectual PMU not supported\n");
    return;
  }
  EXPECT_EQ(status, ZX_OK);

  // Double init doesn't work.
  status = zx_mtrace_control(debug_resource.get(), MTRACE_KIND_PERFMON, MTRACE_PERFMON_INIT, 0,
                             nullptr, 0);
  EXPECT_EQ(status, ZX_ERR_BAD_STATE);

  status = zx_mtrace_control(debug_resource.get(), MTRACE_KIND_PERFMON, MTRACE_PERFMON_FINI, 0,
                             nullptr, 0);
  EXPECT_EQ(status, ZX_OK);

  // Double-fini appears to work.
  status = zx_mtrace_control(debug_resource.get(), MTRACE_KIND_PERFMON, MTRACE_PERFMON_FINI, 0,
                             nullptr, 0);
  EXPECT_EQ(status, ZX_OK);
}

TEST(X86MtraceTestCase, AssignBuffer) {
  zx::result<zx::resource> debug_resource_or_error = GetDebugResource();
  ASSERT_TRUE(debug_resource_or_error.is_ok(), "failed to get debug resource: %s",
              zx_status_get_string(debug_resource_or_error.error_value()));
  zx::resource debug_resource = std::move(debug_resource_or_error.value());
  zx_status_t status = zx_mtrace_control(debug_resource.get(), MTRACE_KIND_PERFMON,
                                         MTRACE_PERFMON_INIT, 0, nullptr, 0);
  if (!IsIntelPMUSupported()) {
    EXPECT_EQ(status, ZX_ERR_NOT_SUPPORTED);
    printf("Skipping test, Intel Architectual PMU not supported\n");
    return;
  }
  EXPECT_EQ(status, ZX_OK);

  // MTRACE_PERFMON_ASSIGN_BUFFER associates a user VMO with each CPU; the VMO is used as a sink
  // for PMU records.
  //
  // IMPLEMENTATION NOTE: MTRACE_PERFMON_ASSIGN_BUFFER does not currently map the buffer into the
  // kernel address space; that is deferred until MTRACE_PERFMON_START. This means that some
  // validation, such as buffer permissions, may be deferred until then, and
  // MTRACE_PERFMON_ASSIGN_BUFFER may appear to work even with invalid buffers.
  uint32_t num_cpus = zx_system_get_num_cpus();
  std::vector<zx_handle_t> vmos(num_cpus);
  for (uint i = 0; i < num_cpus; i++) {
    ASSERT_EQ(zx_vmo_create(PAGE_SIZE, 0, &vmos[i]), ZX_OK);
    int cpu = i;
    zx_pmu_buffer_t buffer = {.vmo = vmos[i]};
    status = zx_mtrace_control(debug_resource.get(), MTRACE_KIND_PERFMON,
                               MTRACE_PERFMON_ASSIGN_BUFFER, cpu, &buffer, sizeof(buffer));
    EXPECT_EQ(status, ZX_OK);
  }

  // Cleanup.
  status = zx_mtrace_control(debug_resource.get(), MTRACE_KIND_PERFMON, MTRACE_PERFMON_FINI, 0,
                             nullptr, 0);
  EXPECT_EQ(status, ZX_OK);
}

// Test a full mtrace MTRACE_KIND_PERFMON cycle - initialize, allocate buffers, configure,
// start/stop tracing, and validate the returned buffers. The test uses a real hardware performance
// counter - the Intel Architectural PMU Fixed-Function Counter 0, 'Instructions Retired'.
TEST(X86MtraceTestCase, InstructionsRetiredFixedCounterTest) {
  perfmon::X86PmuProperties properties;
  zx::result<zx::resource> debug_resource_or_error = GetDebugResource();
  ASSERT_TRUE(debug_resource_or_error.is_ok(), "failed to get debug resource: %s",
              zx_status_get_string(debug_resource_or_error.error_value()));
  zx::resource debug_resource = std::move(debug_resource_or_error.value());

  zx_status_t status =
      zx_mtrace_control(debug_resource.get(), MTRACE_KIND_PERFMON, MTRACE_PERFMON_GET_PROPERTIES, 0,
                        &properties, sizeof(properties));
  if (!IsIntelPMUSupported()) {
    EXPECT_EQ(status, ZX_ERR_NOT_SUPPORTED);
    printf("Skipping test, Intel Architectual PMU not supported\n");
    return;
  }
  ASSERT_EQ(status, ZX_OK);
  status = zx_mtrace_control(debug_resource.get(), MTRACE_KIND_PERFMON, MTRACE_PERFMON_INIT, 0,
                             nullptr, 0);
  EXPECT_EQ(status, ZX_OK);
  uint32_t num_cpus = zx_system_get_num_cpus();
  std::vector<zx_handle_t> vmos(num_cpus);
  for (uint i = 0; i < num_cpus; i++) {
    ASSERT_EQ(zx_vmo_create(PAGE_SIZE, 0, &vmos[i]), ZX_OK);
    int cpu = i;
    zx_pmu_buffer_t buffer = {.vmo = vmos[i]};
    status = zx_mtrace_control(debug_resource.get(), MTRACE_KIND_PERFMON,
                               MTRACE_PERFMON_ASSIGN_BUFFER, cpu, &buffer, sizeof(buffer));
    EXPECT_EQ(status, ZX_OK);
  }

  // Stage a configuation to enable the instructions retired fixed-function counter.
  perfmon::X86PmuConfig config = {};
  config.global_ctrl = (1ul << 32);          // Enable fixed counter 0.
  config.fixed_ctrl = 1;                     // Enabled fixed counter 0 at CPL=0.
  config.fixed_events[0] = (2ul << 11) | 1;  // kGroupFixed | Instructions retired.
  status = zx_mtrace_control(debug_resource.get(), MTRACE_KIND_PERFMON, MTRACE_PERFMON_STAGE_CONFIG,
                             0, &config, sizeof(config));
  EXPECT_EQ(status, ZX_OK);

  // Start and stop tracing. Each will execute some code at CPL=0.
  status = zx_mtrace_control(debug_resource.get(), MTRACE_KIND_PERFMON, MTRACE_PERFMON_START, 0,
                             nullptr, 0);
  EXPECT_EQ(status, ZX_OK);
  status = zx_mtrace_control(debug_resource.get(), MTRACE_KIND_PERFMON, MTRACE_PERFMON_STOP, 0,
                             nullptr, 0);
  EXPECT_EQ(status, ZX_OK);

  status = zx_mtrace_control(debug_resource.get(), MTRACE_KIND_PERFMON, MTRACE_PERFMON_FINI, 0,
                             nullptr, 0);
  EXPECT_EQ(status, ZX_OK);
  // Examine the buffers; each buffer should have a fixed length BufferHeader followed by one or
  // more variable-length Records. Each Record has a common header.
  struct Buffer {
    perfmon::BufferHeader header;
    char data[PAGE_SIZE - sizeof(perfmon::BufferHeader)];
  };
  static_assert(sizeof(Buffer) == PAGE_SIZE);
  for (uint i = 0; i < num_cpus; i++) {
    Buffer buffer = {};
    status = zx_vmo_read(vmos[i], &buffer, 0, sizeof(Buffer));
    EXPECT_EQ(status, ZX_OK);
    EXPECT_EQ(buffer.header.version, 0);
    EXPECT_EQ(buffer.header.arch, 1);  // Arch X86
    // Expect at least one record.
    EXPECT_GT(buffer.header.capture_end, sizeof(buffer.header));
    // First record must be a time record.
    perfmon::RecordHeader* const record = reinterpret_cast<perfmon::RecordHeader*>(buffer.data);
    EXPECT_EQ(record->type, perfmon::kRecordTypeTime);
  }
}

}  // namespace
