// Copyright 2023 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 "acpi.h"

#include <lib/stdcompat/span.h>
#include <lib/zbi-format/cpu.h>
#include <lib/zbi-format/driver-config.h>
#include <stdio.h>
#include <zircon/assert.h>

#include <algorithm>
#include <numeric>

#include <efi/types.h>
#include <phys/efi/main.h>

namespace gigaboot {

namespace {

struct AcpiRsdpRevisionDescription {
  uint8_t revision;
  AcpiTableSignature signature;
  size_t entry_size;
  const SdtHeader* (*accessor)(const AcpiRsdp&);
};

// Describes the invariants for different revisions of the SDT table.
// Note: newer revisions MUST add entries at the beginning of the array
//       so that when searching forward we find the NEWEST description
//       that is not greater than the RSDP we are using.
//
// Note: in C++20, it is possible to validate this invariant in a static assert.
//       Older language versions don't have sufficient support for constexpr to allow
//       the check statically.
constexpr AcpiRsdpRevisionDescription kRevisionTable[] = {

    {
        .revision = 1,
        .signature = kXsdtSignature,
        .entry_size = sizeof(AcpiRsdp::xsdt_address),
        .accessor =
            [](const auto& entry) {
              return reinterpret_cast<const SdtHeader*>(entry.xsdt_address);
            },
    },
    {
        .revision = 0,
        .signature = kRsdtSignature,
        .entry_size = sizeof(AcpiRsdp::rsdt_address),
        .accessor =
            [](const auto& entry) {
              return reinterpret_cast<const SdtHeader*>(
                  static_cast<efi_physical_addr>(entry.rsdt_address));
            },
    },
};

template <typename PtrNum>
const SdtHeader* TraverseEntries(const SdtHeader* table, AcpiTableSignature sig) {
  static_assert(std::numeric_limits<PtrNum>::is_integer);

  // The array of entry pointers is not guaranteed to be correctly aligned,
  // so we memcpy the entries into a local array.
  // 32 is an educated guess about the maximum number of headers in the array.
  size_t num_entries = (table->length - sizeof(*table)) / sizeof(PtrNum);
  std::array<PtrNum, 32> aligned_ptrs;
  cpp20::span<PtrNum> aligned_ptr_span(aligned_ptrs.begin(),
                                       std::min(num_entries, aligned_ptrs.size()));
  memcpy(aligned_ptr_span.data(), reinterpret_cast<const uint8_t*>(table + 1),
         aligned_ptr_span.size_bytes());

  for (const auto addr : aligned_ptr_span) {
    const auto* entry = reinterpret_cast<const SdtHeader*>(addr);
    if (entry && entry->signature == sig) {
      return entry;
    }
  }
  return nullptr;
}

}  // namespace

std::optional<zbi_dcfg_arm_psci_driver_t> AcpiFadt::GetPsciDriver() const {
  if (!(arm_boot_arch & kPsciCompliant)) {
    return std::nullopt;
  }

  return zbi_dcfg_arm_psci_driver_t{
      .use_hvc = static_cast<uint8_t>(arm_boot_arch & kPsciUseHvc),
  };
}

zbi_dcfg_arm_generic_timer_driver_t AcpiGtdt::GetTimer() const {
  return {
      .irq_phys = nonsecure_el1_timer_gsiv,
      .irq_virt = virtual_el1_timer_gsiv,
  };
}

const SdtHeader* AcpiRsdp::LoadTableWithSignature(AcpiTableSignature sig) const {
  // Note the requirement for listing newer revisions first in the definition of kRevisionTable
  const auto lookup = std::find_if(std::cbegin(kRevisionTable), std::cend(kRevisionTable),
                                   [&](const auto& entry) { return revision >= entry.revision; });

  if (lookup == std::cend(kRevisionTable)) {
    printf("%s: invalid RSDP revision: %u\n", __func__, revision);
    return nullptr;
  }

  const SdtHeader* sdt_table = lookup->accessor(*this);
  if (sdt_table == nullptr) {
    printf("%s: null entry for SDT table\n", __func__);
    return nullptr;
  }

  if (sdt_table->signature != lookup->signature) {
    printf("%s: bad signature for SDT table with revision %u: %.*s\n", __func__, revision,
           static_cast<int>(sdt_table->signature.size()), sdt_table->signature.data());
    return nullptr;
  }

  if (lookup->entry_size == sizeof(uint64_t)) {
    return TraverseEntries<uint64_t>(sdt_table, sig);
  }

  if (lookup->entry_size == sizeof(uint32_t)) {
    return TraverseEntries<uint32_t>(sdt_table, sig);
  }

  ZX_ASSERT(false);
  return nullptr;
}

uint32_t AcpiSpcr::GetKdrv() const {
  // The SPCR table does not contain the granular subtype of the register
  // interface we need in revision 1, so return early in this case.
  if (hdr.revision < 2) {
    return 0;
  }

  // The SPCR types are documented in Table 3 on:
  // https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/acpi-debug-port-table
  // We currently only rely on PL011 devices to be initialized here.
  switch (interface_type) {
    case 0x0003:
      return ZBI_KERNEL_DRIVER_PL011_UART;
    default:
      printf("%s: unsupported serial interface type: 0x%x\n", __func__, interface_type);
      return 0;
  }
}

cpp20::span<zbi_topology_node_t> AcpiMadt::GetTopology(
    cpp20::span<zbi_topology_node_t> nodes) const {
  auto last_node = nodes.begin();

  for (const auto& controller : controllers()) {
    const auto* gicc = GetInterruptController<AcpiMadtGicInterface>(controller);
    if (gicc == nullptr) {
      continue;
    }

    if (last_node == nodes.end()) {
      return nodes;
    }

    size_t num_cpus = std::distance(nodes.begin(), last_node);
    *last_node = zbi_topology_node_t{
        .entity =
            {
                .discriminant = ZBI_TOPOLOGY_ENTITY_PROCESSOR,
                .processor =
                    {
                        .architecture_info =
                            {
                                .discriminant = ZBI_TOPOLOGY_ARCHITECTURE_INFO_ARM64,
                                .arm64 =
                                    {
                                        .cluster_1_id =
                                            static_cast<uint8_t>((gicc->mpidr >> 8) & 0xFF),
                                        .cluster_2_id =
                                            static_cast<uint8_t>((gicc->mpidr >> 16) & 0xFF),
                                        .cluster_3_id =
                                            static_cast<uint8_t>((gicc->mpidr >> 32) & 0xFF),
                                        .cpu_id = static_cast<uint8_t>(gicc->mpidr & 0xFF),
                                        .gic_id = static_cast<uint8_t>(gicc->cpu_interface_number),
                                    },
                            },
                        .flags = static_cast<zbi_topology_processor_flags_t>(
                            (num_cpus) ? ZBI_TOPOLOGY_PROCESSOR_FLAGS_PRIMARY : 0),
                        .logical_ids = {static_cast<uint16_t>(num_cpus)},
                        .logical_id_count = 1,
                    },
            },
        .parent_index = ZBI_TOPOLOGY_NO_PARENT,

    };
    ++last_node;
  }

  return cpp20::span<zbi_topology_node_t>(nodes.begin(), last_node);
}

std::optional<AcpiMadt::GicDescriptor> AcpiMadt::GetGicDriver() const {
  const AcpiMadtGicInterface* gicc = nullptr;
  const AcpiMadtGicDistributor* gicd = nullptr;
  const AcpiGicMsi* gic_msi = nullptr;
  const AcpiMadtGicRedistributor* gicr = nullptr;

  for (const auto& controller : controllers()) {
    switch (controller.type) {
      case AcpiMadtGicInterface::kType:
        gicc = GetInterruptController<AcpiMadtGicInterface>(controller);
        break;
      case AcpiMadtGicDistributor::kType:
        gicd = GetInterruptController<AcpiMadtGicDistributor>(controller);
        break;
      case AcpiMadtGicRedistributor::kType:
        gicr = GetInterruptController<AcpiMadtGicRedistributor>(controller);
        break;
      case AcpiGicMsi::kType:
        gic_msi = GetInterruptController<AcpiGicMsi>(controller);
        break;
      default:
        printf("%s: unexpected interrupt controller type: 0x%x\n", __func__, controller.type);
        break;
    }
  }

  if (gicd == nullptr) {
    printf("%s: no valid gicd found\n", __func__);
    return std::nullopt;
  }
  uint64_t mmio_phys_addr = gicd->physical_base_address;
  switch (gicd->gic_version) {
    case 0x02:
      if (gicc == nullptr) {
        printf("%s: No gicc\n", __func__);
        return std::nullopt;
      }
      mmio_phys_addr = std::min(gicc->physical_base_address, mmio_phys_addr);
      return AcpiMadt::GicDescriptor{
          .driver =
              zbi_dcfg_arm_gic_v2_driver_t{
                  .mmio_phys = mmio_phys_addr,
                  .msi_frame_phys = gic_msi->physical_base_address,
                  .gicd_offset = gicd->physical_base_address - mmio_phys_addr,
                  .gicc_offset = gicc->physical_base_address - mmio_phys_addr,
                  .ipi_base = 0,
                  .optional = true,
                  .use_msi = gic_msi != nullptr,
              },
          .zbi_type = ZBI_KERNEL_DRIVER_ARM_GIC_V2,
      };
    case 0x03:
      if (gicr == nullptr) {
        printf("%s: No gicr\n", __func__);
        return std::nullopt;
      }
      mmio_phys_addr = std::min(gicr->discovery_range_base_address, mmio_phys_addr);
      return AcpiMadt::GicDescriptor{
          .driver =
              zbi_dcfg_arm_gic_v3_driver_t{
                  .mmio_phys = mmio_phys_addr,
                  .gicd_offset = gicd->physical_base_address - mmio_phys_addr,
                  .gicr_offset = gicr->discovery_range_base_address - mmio_phys_addr,
                  .gicr_stride = kGicv3rDefaultStride,
                  .ipi_base = 0,
                  .optional = true,
              },
          .zbi_type = ZBI_KERNEL_DRIVER_ARM_GIC_V3,
      };
    default:
      printf("%s: unexpected gic version: %u\n", __func__, gicd->gic_version);
      return std::nullopt;
  }
}

zbi_dcfg_simple_t AcpiSpcr::DeriveUartDriver() const {
  return {
      .mmio_phys = base_address.address,
      // IRQ is only valid if the lowest order bit of interrupt type is set.
      // Any other bit set to 1 in the interrupt type indicates that we should
      // use the Global System Interrupt (GSIV).
      .irq = (0x1 & interrupt_type) ? irq : gsiv,
  };
}

const AcpiRsdp* FindAcpiRsdp() {
  const AcpiRsdp* rsdp = nullptr;
  cpp20::span<const efi_configuration_table> entries(gEfiSystemTable->ConfigurationTable,
                                                     gEfiSystemTable->NumberOfTableEntries);

  for (const efi_configuration_table& entry : entries) {
    // Check if this entry is an ACPI RSD PTR.
    const auto* vendor_table = reinterpret_cast<const std::array<uint8_t, 8>*>(entry.VendorTable);
    if ((entry.VendorGuid == kAcpiTableGuid || entry.VendorGuid == kAcpi20TableGuid) &&
        // Verify the signature of the ACPI RSD PTR.
        vendor_table && *vendor_table == kAcpiRsdpSignature) {
      rsdp = reinterpret_cast<const AcpiRsdp*>(entry.VendorTable);
      break;
    }
  }

  if (rsdp == nullptr) {
    printf("RSDP was not found\n");
    return nullptr;
  }

  // Verify the checksum of this table. Both V1 and V2 RSDPs should pass the
  // V1 checksum, which only covers the first 20 bytes of the table.
  // The checksum adds all the bytes and passes if the result is 0.
  cpp20::span<const uint8_t> acpi_bytes(reinterpret_cast<const uint8_t*>(rsdp), kAcpiRsdpV1Size);
  if (uint8_t res = std::reduce(acpi_bytes.begin(), acpi_bytes.end(), 0ull) & 0xFF; res) {
    printf("RSDP V1 checksum failed\n");
    return nullptr;
  }

  // V2 RSDPs should additionally pass a checksum of the entire table.
  if (rsdp->revision > 0) {
    acpi_bytes = {acpi_bytes.begin(), rsdp->length};
    if (uint8_t res = static_cast<uint8_t>(std::reduce(acpi_bytes.begin(), acpi_bytes.end(), 0));
        res) {
      printf("RSDP V2 checksum failed\n");
      return nullptr;
    }
  }

  return rsdp;
}

}  // namespace gigaboot
