// 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 <gtest/gtest.h>

#include "src/developer/debug/debug_agent/arch.h"
#include "src/developer/debug/debug_agent/test_utils.h"
#include "src/developer/debug/shared/logging/file_line_function.h"
#include "src/developer/debug/shared/register_test_support.h"
#include "src/developer/debug/shared/zx_status.h"

namespace debug_agent {
namespace arch {

TEST(ArchArm64, WriteGeneralRegs) {
  std::vector<debug::RegisterValue> regs;
  regs.push_back(debug::CreateRegisterWithTestData(debug::RegisterID::kARMv8_x0, 8));
  regs.push_back(debug::CreateRegisterWithTestData(debug::RegisterID::kARMv8_x3, 8));
  regs.push_back(debug::CreateRegisterWithTestData(debug::RegisterID::kARMv8_lr, 8));
  regs.push_back(debug::CreateRegisterWithTestData(debug::RegisterID::kARMv8_pc, 8));

  zx_thread_state_general_regs_t out = {};
  zx_status_t res = WriteGeneralRegisters(regs, &out);
  ASSERT_EQ(res, ZX_OK) << "Expected ZX_OK, got " << debug::ZxStatusToString(res);

  EXPECT_EQ(out.r[0], 0x0102030405060708u);
  EXPECT_EQ(out.r[1], 0u);
  EXPECT_EQ(out.r[2], 0u);
  EXPECT_EQ(out.r[3], 0x0102030405060708u);
  EXPECT_EQ(out.r[4], 0u);
  EXPECT_EQ(out.r[29], 0u);
  EXPECT_EQ(out.lr, 0x0102030405060708u);
  EXPECT_EQ(out.pc, 0x0102030405060708u);

  regs.clear();
  regs.emplace_back(debug::RegisterID::kARMv8_x0, static_cast<uint64_t>(0xaabb));
  regs.emplace_back(debug::RegisterID::kARMv8_x15, static_cast<uint64_t>(0xdead));
  regs.emplace_back(debug::RegisterID::kARMv8_pc, static_cast<uint64_t>(0xbeef));

  res = WriteGeneralRegisters(regs, &out);
  ASSERT_EQ(res, ZX_OK) << "Expected ZX_OK, got " << debug::ZxStatusToString(res);

  EXPECT_EQ(out.r[0], 0xaabbu);
  EXPECT_EQ(out.r[1], 0u);
  EXPECT_EQ(out.r[15], 0xdeadu);
  EXPECT_EQ(out.r[29], 0u);
  EXPECT_EQ(out.lr, 0x0102030405060708u);
  EXPECT_EQ(out.pc, 0xbeefu);
}

TEST(ArchArm64, InvalidWriteGeneralRegs) {
  zx_thread_state_general_regs_t out;
  std::vector<debug::RegisterValue> regs;

  // Invalid length.
  regs.push_back(debug::CreateRegisterWithTestData(debug::RegisterID::kARMv8_v0, 4));
  EXPECT_EQ(WriteGeneralRegisters(regs, &out), ZX_ERR_INVALID_ARGS);

  // Invalid (non-canonical) register.
  regs.push_back(debug::CreateRegisterWithTestData(debug::RegisterID::kARMv8_w3, 8));
  EXPECT_EQ(WriteGeneralRegisters(regs, &out), ZX_ERR_INVALID_ARGS);
}

TEST(ArchArm64, WriteVectorRegs) {
  std::vector<debug::RegisterValue> regs;

  std::vector<uint8_t> v0_value;
  v0_value.resize(16);
  v0_value.front() = 0x42;
  v0_value.back() = 0x12;
  regs.emplace_back(debug::RegisterID::kARMv8_v0, v0_value);

  std::vector<uint8_t> v31_value = v0_value;
  v31_value.front()++;
  v31_value.back()++;
  regs.emplace_back(debug::RegisterID::kARMv8_v31, v31_value);

  regs.emplace_back(debug::RegisterID::kARMv8_fpcr, std::vector<uint8_t>{5, 6, 7, 8});
  regs.emplace_back(debug::RegisterID::kARMv8_fpsr, std::vector<uint8_t>{9, 0, 1, 2});

  zx_thread_state_vector_regs_t out = {};
  zx_status_t res = WriteVectorRegisters(regs, &out);
  ASSERT_EQ(res, ZX_OK) << "Expected ZX_OK, got " << debug::ZxStatusToString(res);

  EXPECT_EQ(out.v[0].low, 0x0000000000000042u);
  EXPECT_EQ(out.v[0].high, 0x1200000000000000u);
  EXPECT_EQ(out.v[31].low, 0x0000000000000043u);
  EXPECT_EQ(out.v[31].high, 0x1300000000000000u);

  EXPECT_EQ(out.fpcr, 0x08070605u);
  EXPECT_EQ(out.fpsr, 0x02010009u);
}

TEST(ArchArm64, WriteDebugRegs) {
  std::vector<debug::RegisterValue> regs;
  regs.emplace_back(debug::RegisterID::kARMv8_dbgbcr0_el1, std::vector<uint8_t>{1, 2, 3, 4});
  regs.emplace_back(debug::RegisterID::kARMv8_dbgbcr1_el1, std::vector<uint8_t>{2, 3, 4, 5});
  regs.emplace_back(debug::RegisterID::kARMv8_dbgbcr15_el1, std::vector<uint8_t>{3, 4, 5, 6});

  regs.emplace_back(debug::RegisterID::kARMv8_dbgbvr0_el1,
                    std::vector<uint8_t>{4, 5, 6, 7, 8, 9, 0, 1});
  regs.emplace_back(debug::RegisterID::kARMv8_dbgbvr1_el1,
                    std::vector<uint8_t>{5, 6, 7, 8, 9, 0, 1, 2});
  regs.emplace_back(debug::RegisterID::kARMv8_dbgbvr15_el1,
                    std::vector<uint8_t>{6, 7, 8, 9, 0, 1, 2, 3});

  // TODO(bug 40992) Add ARM64 hardware watchpoint registers here.

  zx_thread_state_debug_regs_t out = {};
  zx_status_t res = WriteDebugRegisters(regs, &out);
  ASSERT_EQ(res, ZX_OK) << "Expected ZX_OK, got " << debug::ZxStatusToString(res);

  EXPECT_EQ(out.hw_bps[0].dbgbcr, 0x04030201u);
  EXPECT_EQ(out.hw_bps[1].dbgbcr, 0x05040302u);
  EXPECT_EQ(out.hw_bps[15].dbgbcr, 0x06050403u);
  EXPECT_EQ(out.hw_bps[0].dbgbvr, 0x0100090807060504u);
  EXPECT_EQ(out.hw_bps[1].dbgbvr, 0x0201000908070605u);
  EXPECT_EQ(out.hw_bps[15].dbgbvr, 0x0302010009080706u);
}

TEST(ArchArm64, ReadTPIDR) {
  zx_thread_state_general_regs_t regs_in;
  regs_in.tpidr = 0xdeadbeeff00dbabe;

  std::vector<debug::RegisterValue> regs_out;
  arch::SaveGeneralRegs(regs_in, regs_out);

  const debug::RegisterValue* found = nullptr;
  for (const auto& reg : regs_out) {
    if (reg.id == debug::RegisterID::kARMv8_tpidr) {
      found = &reg;
      break;
    }
  }

  ASSERT_NE(nullptr, found);
  ASSERT_GE(8u, found->data.size());
  EXPECT_EQ(8u, found->data.size());

  EXPECT_EQ(0xbe, found->data[0]);
  EXPECT_EQ(0xba, found->data[1]);
  EXPECT_EQ(0x0d, found->data[2]);
  EXPECT_EQ(0xf0, found->data[3]);
  EXPECT_EQ(0xef, found->data[4]);
  EXPECT_EQ(0xbe, found->data[5]);
  EXPECT_EQ(0xad, found->data[6]);
  EXPECT_EQ(0xde, found->data[7]);
}

}  // namespace arch
}  // namespace debug_agent
