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

#include <memory>

#include <ddk/debug.h>
#include <ddk/platform-defs.h>
#include <fbl/alloc_checker.h>
#include <fbl/auto_call.h>

#include "qemu-bus.h"
#include "qemu-virt.h"
#include "zircon/errors.h"
#include "zircon/syscalls/types.h"

namespace board_qemu_arm64 {

zx_status_t QemuArm64::PciInit() {
  zx_status_t status;

  zx_pci_init_arg_t* arg1;
  size_t arg_size = sizeof(*arg1) + sizeof(arg1->addr_windows[0]);  // room for one addr window
  fbl::AllocChecker ac;
  std::unique_ptr<uint8_t[]> buf(new (&ac) uint8_t[arg_size]);
  if (!ac.check()) {
    return ZX_ERR_NO_MEMORY;
  }
  auto* arg = reinterpret_cast<zx_pci_init_arg_t*>(buf.get());

  // Please do not use get_root_resource() in new code. See ZX-1467.
  status = zx_pci_add_subtract_io_range(get_root_resource(), true /* mmio */, PCIE_MMIO_BASE_PHYS,
                                        PCIE_MMIO_SIZE, true /* add */);
  if (status != ZX_OK) {
    return status;
  }
  // Please do not use get_root_resource() in new code. See ZX-1467.
  status = zx_pci_add_subtract_io_range(get_root_resource(), false /* pio */, PCIE_PIO_BASE_PHYS,
                                        PCIE_PIO_SIZE, true /* add */);
  if (status != ZX_OK) {
    return status;
  }

  // initialize our swizzle table
  zx_pci_irq_swizzle_lut_t* lut = &arg->dev_pin_to_global_irq;
  for (unsigned dev_id = 0; dev_id < ZX_PCI_MAX_DEVICES_PER_BUS; dev_id++) {
    for (unsigned func_id = 0; func_id < ZX_PCI_MAX_FUNCTIONS_PER_DEVICE; func_id++) {
      for (unsigned pin = 0; pin < ZX_PCI_MAX_LEGACY_IRQ_PINS; pin++) {
        (*lut)[dev_id][func_id][pin] = PCIE_INT_BASE + (pin + dev_id) % ZX_PCI_MAX_LEGACY_IRQ_PINS;
      }
    }
  }
  arg->num_irqs = 0;
  arg->addr_window_count = 1;
  arg->addr_windows[0].cfg_space_type = PCI_CFG_SPACE_TYPE_MMIO;
  arg->addr_windows[0].has_ecam = true;
  arg->addr_windows[0].base = PCIE_ECAM_BASE_PHYS;
  arg->addr_windows[0].size = PCIE_ECAM_SIZE;
  arg->addr_windows[0].bus_start = 0;
  arg->addr_windows[0].bus_end = (PCIE_ECAM_SIZE / ZX_PCI_ECAM_BYTE_PER_BUS) - 1;

  // Please do not use get_root_resource() in new code. See ZX-1467.
  status = zx_pci_init(get_root_resource(), arg, static_cast<uint32_t>(arg_size));
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: error %d in zx_pci_init\n", __func__, status);
    return status;
  }

  return ZX_OK;
}

zx_status_t QemuArm64::PciAdd() {
  constexpr pbus_bti_t kPciBtis[] = {
      {
          .iommu_index = 0,
          .bti_id = 0,
      },
  };

  pbus_dev_t pci_dev = {};
  pci_dev.name = "pci";
  pci_dev.vid = PDEV_VID_GENERIC;
  pci_dev.pid = PDEV_PID_GENERIC;
  pci_dev.did = PDEV_DID_KPCI;
  pci_dev.bti_list = kPciBtis;
  pci_dev.bti_count = countof(kPciBtis);

  auto status = pbus_.DeviceAdd(&pci_dev);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: DeviceAdd failed %d\n", __func__, status);
    return status;
  }

  return ZX_OK;
}

}  // namespace board_qemu_arm64
