// Copyright 2017 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 "src/virtualization/bin/vmm/pci.h"

#include <lib/async/default.h>
#include <lib/pci/hw.h>

#include <gtest/gtest.h>

#include "src/virtualization/bin/vmm/bits.h"

namespace {

static constexpr uint16_t kPciConfigAddrPortBase = 0;
static constexpr uint16_t kPciConfigDataPortBase = 4;

constexpr uint64_t pci_type1_addr(uint8_t bus, uint8_t device, uint8_t function, uint8_t reg) {
  return 0x80000000 | (bus << 16) | (device << 11) | (function << 8) | pci_type1_register(reg);
}

// Test we can read multiple fields in 1 32-bit word.
TEST(PciDeviceTest, ReadConfigRegister) {
  Guest guest;
  PciBus bus(&guest, nullptr);
  bus.Init(async_get_default_dispatcher());
  PciDevice* device = bus.root_complex();

  // Access Vendor/Device ID as a single 32bit read.
  IoValue value = {};
  value.access_size = 4;
  EXPECT_EQ(device->ReadConfig(PCI_CONFIG_VENDOR_ID, &value), ZX_OK);
  EXPECT_EQ(value.u32, PCI_VENDOR_ID_INTEL | (PCI_DEVICE_ID_INTEL_Q35 << 16));
}

// Verify we can read portions of a 32 bit word, one byte at a time.
TEST(PciDeviceTest, ReadConfigRegisterBytewise) {
  Guest guest;
  PciBus bus(&guest, nullptr);
  bus.Init(async_get_default_dispatcher());
  PciDevice* device = bus.root_complex();

  uint32_t expected_device_vendor = PCI_VENDOR_ID_INTEL | (PCI_DEVICE_ID_INTEL_Q35 << 16);
  for (int i = 0; i < 4; ++i) {
    uint16_t reg = static_cast<uint16_t>(PCI_CONFIG_VENDOR_ID + i);
    IoValue value = {};
    value.access_size = 1;
    EXPECT_EQ(device->ReadConfig(reg, &value), ZX_OK);
    EXPECT_EQ(value.u32, bits_shift(expected_device_vendor, i * 8 + 7, i * 8));
  }
}

// PCI devices BAR sizes must be a power of 2 and must not support setting any
// bits in the BAR that are not size aligned. Software often relies on this to
// read the bar size by writing all 1's to the register and reading back the
// value.
//
// This tests that we properly mask the lowest bits so software can compute the
// BAR size.
TEST(PciDeviceTest, ReadBarSize) {
  Guest guest;
  PciBus bus(&guest, nullptr);
  bus.Init(async_get_default_dispatcher());
  PciDevice* device = bus.root_complex();

  // Set all bits in the BAR register. The device will ignore writes to the
  // LSBs which we can read out to determine the size.
  IoValue value;
  value.access_size = 4;
  value.u32 = UINT32_MAX;
  EXPECT_EQ(device->WriteConfig(PCI_CONFIG_BASE_ADDRESSES + 0, value), ZX_OK);
  EXPECT_EQ(device->WriteConfig(PCI_CONFIG_BASE_ADDRESSES + 4, value), ZX_OK);

  // PCI Express Base Specification, Rev. 4.0 Version 1.0, Section 7.5.1.2.1:
  // Base Address Registers
  //
  // Software saves the original value of the Base Address register, writes a
  // value of all 1's to the register, then reads it back. Size calculation can
  // be done from the 32 bit value read by first clearing encoding information
  // bits (bits 1:0 for I/O, bits 3:0 for memory), inverting all 32 bits
  // (logical NOT), then incrementing by 1. The resultant 32-bit value is the
  // memory/I/O range size decoded by the register. Note that the upper 16 bits
  // of the result is ignored if the Base Address register is for I/O and bits
  // 31:16 returned zero upon read. The original value in the Base Address
  // register is restored before re-enabling decode in the Command register of
  // the Function.
  //
  // 64-bit (memory) Base Address registers can be handled the same, except that
  // the second 32 bit register is considered an extension of the first (i.e.,
  // bits 63:32). Software writes a value of all 1's to both registers, reads
  // them back, and combines the result into a 64-bit value. Size calculation is
  // done on the 64-bit value.

  // Read out BAR and compute size.
  value.access_size = 4;
  value.u32 = 0;
  EXPECT_EQ(device->ReadConfig(PCI_CONFIG_BASE_ADDRESSES + 0, &value), ZX_OK);
  uint64_t reg = value.u32;
  EXPECT_EQ(device->ReadConfig(PCI_CONFIG_BASE_ADDRESSES + 4, &value), ZX_OK);
  reg |= static_cast<uint64_t>(value.u32) << 32;

  EXPECT_EQ(reg & ~kPciBarMmioAddrMask, kPciBarMmioType64Bit | kPciBarMmioAccessSpace);
  const PciBar* bar = device->bar(0);
  EXPECT_TRUE(bar != nullptr);
  EXPECT_EQ(~(reg & kPciBarMmioAddrMask) + 1, bar->size);
}

// Verify stats & cap registers correctly show present capabilities and that
// capability data is readable.
TEST(PciDeviceTest, ReadCapability) {
  Guest guest;
  PciBus bus(&guest, nullptr);
  bus.Init(async_get_default_dispatcher());
  PciDevice* device = bus.root_complex();

  // Create and install a simple capability. First two bytes are ignored.
  uint8_t cap_data[] = {0, 0, 0xf, 0xa};
  pci_cap_t cap = {
      .id = 0x9,
      .data = cap_data,
      .len = sizeof(cap_data),
  };
  device->set_capabilities(&cap, 1);

  // PCI Local Bus Spec 3.0 Table 6-2: Status Register Bits
  //
  // This optional read-only bit indicates whether or not this device
  // implements the pointer for a New Capabilities linked list at offset 34h.
  // A value of zero indicates that no New Capabilities linked list is
  // available. A value of one indicates that the value read at offset 34h is
  // a pointer in Configuration Space to a linked list of new capabilities.
  // Refer to Section 6.7 for details on New Capabilities.
  IoValue status;
  status.access_size = 2;
  status.u16 = 0;
  EXPECT_EQ(device->ReadConfig(PCI_CONFIG_STATUS, &status), ZX_OK);
  EXPECT_TRUE(status.u16 & PCI_STATUS_NEW_CAPS);

  // Read the cap pointer from config space. Here just verify it points to
  // some location beyond the pre-defined header.
  IoValue cap_ptr;
  cap_ptr.access_size = 1;
  cap_ptr.u8 = 0;
  EXPECT_EQ(device->ReadConfig(PCI_CONFIG_CAPABILITIES, &cap_ptr), ZX_OK);
  EXPECT_LT(0x40u, cap_ptr.u8);

  // Read the capability. This will be the Cap ID, next pointer (0), followed
  // by data bytes (starting at index 2).
  IoValue cap_value;
  cap_value.access_size = 4;
  cap_value.u32 = 0;
  EXPECT_EQ(device->ReadConfig(cap_ptr.u8, &cap_value), ZX_OK);
  EXPECT_EQ(0x0a0f0009u, cap_value.u32);
}

// Build a list of capabilities with no data (only the required ID/next
// fields). Verify the next pointers are correctly wired up to traverse
// the linked list.
TEST(PciDeviceTest, ReadChainedCapability) {
  Guest guest;
  PciBus bus(&guest, nullptr);
  bus.Init(async_get_default_dispatcher());
  PciDevice* device = bus.root_complex();

  // Build list of caps.
  pci_cap_t caps[5];
  size_t num_caps = sizeof(caps) / sizeof(caps[0]);
  for (uint8_t i = 0; i < num_caps; ++i) {
    caps[i].id = i;
    caps[i].len = 2;
  }
  device->set_capabilities(caps, num_caps);

  IoValue cap_ptr;
  cap_ptr.access_size = 1;
  cap_ptr.u8 = 0;
  EXPECT_EQ(device->ReadConfig(PCI_CONFIG_CAPABILITIES, &cap_ptr), ZX_OK);
  for (uint8_t i = 0; i < num_caps; ++i) {
    IoValue cap_header;
    cap_header.access_size = 4;
    cap_header.u32 = 0;

    // Read the current capability.
    EXPECT_EQ(device->ReadConfig(cap_ptr.u8, &cap_header), ZX_OK);
    // ID is the first byte.
    EXPECT_EQ(i, cap_header.u32 & UINT8_MAX);
    // Next pointer is the second byte.
    cap_ptr.u8 = static_cast<uint8_t>(cap_header.u32 >> 8);
  }
  EXPECT_EQ(0u, cap_ptr.u8);
}

// Test accesses to the PCI config address ports.
//
// Access to the 32-bit PCI config address port is provided by the IO ports
// 0xcf8 - 0xcfb. Accesses to each port must have the same alignment as the
// port address used.
//
// The device operates on relative port addresses so we'll use 0-3 instead of
// 0cf8-0xcfb
//
// Ex:
//  -------------------------------------
// | port  | valid access widths (bytes) |
// --------------------------------------|
// |   0   | 1, 2, 4                     |
// |   1   | 1                           |
// |   2   | 1, 2                        |
// |   3   | 1                           |
//  -------------------------------------
TEST(PciBusTest, WriteConfigAddressPort) {
  Guest guest;
  PciBus bus(&guest, nullptr);
  bus.Init(async_get_default_dispatcher());

  // 32 bit write.
  IoValue value;
  value.access_size = 4;
  value.u32 = 0x12345678;
  EXPECT_EQ(bus.WriteIoPort(kPciConfigAddrPortBase, value), ZX_OK);
  EXPECT_EQ(bus.config_addr(), 0x12345678u);

  // 16 bit write to bits 31..16. Other bits remain unchanged.
  value.access_size = 2;
  value.u16 = 0xFACE;
  EXPECT_EQ(bus.WriteIoPort(kPciConfigAddrPortBase + 2, value), ZX_OK);
  EXPECT_EQ(bus.config_addr(), 0xFACE5678u);

  // 8 bit write to bits (15..8). Other bits remain unchanged.
  value.access_size = 1;
  value.u8 = 0x99;
  EXPECT_EQ(bus.WriteIoPort(kPciConfigAddrPortBase + 1, value), ZX_OK);
  EXPECT_EQ(bus.config_addr(), 0xFACE9978u);
}

// Test reading the PCI config address ports.
//
// See pci_bus_write_config_addr_port for more details.
TEST(PciBusTest, ReadConfigAddressPort) {
  Guest guest;
  PciBus bus(&guest, nullptr);
  bus.Init(async_get_default_dispatcher());
  bus.set_config_addr(0x12345678);

  // 32 bit read (bits 31..0).
  IoValue value = {};
  value.access_size = 4;
  EXPECT_EQ(bus.ReadIoPort(kPciConfigAddrPortBase, &value), ZX_OK);
  EXPECT_EQ(value.access_size, 4);
  EXPECT_EQ(value.u32, 0x12345678u);

  // 16 bit read (bits 31..16).
  value.access_size = 2;
  value.u16 = 0;
  EXPECT_EQ(bus.ReadIoPort(kPciConfigAddrPortBase + 2, &value), ZX_OK);
  EXPECT_EQ(value.access_size, 2);
  EXPECT_EQ(value.u16, 0x1234u);

  // 8 bit read (bits 15..8).
  value.access_size = 1;
  value.u8 = 0;
  EXPECT_EQ(bus.ReadIoPort(kPciConfigAddrPortBase + 1, &value), ZX_OK);
  EXPECT_EQ(value.access_size, 1);
  EXPECT_EQ(value.u8, 0x56u);
}

// The address written to the data port (0xcf8) is 4b aligned. The offset into
// the data port range 0xcfc-0xcff is added to the address to access partial
// words.
TEST(PciBusTest, ReadConfigDataPort) {
  Guest guest;
  PciBus bus(&guest, nullptr);
  bus.Init(async_get_default_dispatcher());
  IoValue value = {};

  // 16-bit read.
  bus.set_config_addr(pci_type1_addr(0, 0, 0, 0));
  value.access_size = 2;
  EXPECT_EQ(bus.ReadIoPort(kPciConfigDataPortBase, &value), ZX_OK);
  EXPECT_EQ(value.access_size, 2);
  EXPECT_EQ(value.u16, PCI_VENDOR_ID_INTEL);

  // 32-bit read from same address. Result should now contain the Device ID
  // in the upper 16 bits
  value.access_size = 4;
  value.u32 = 0;
  EXPECT_EQ(bus.ReadIoPort(kPciConfigDataPortBase, &value), ZX_OK);
  EXPECT_EQ(value.access_size, 4);
  EXPECT_EQ(value.u32, PCI_VENDOR_ID_INTEL | (PCI_DEVICE_ID_INTEL_Q35 << 16));

  // 16-bit read of upper half-word.
  //
  // Device ID is 2b aligned and the PCI config address register can only hold
  // a 4b aligned address. The offset into the word addressed by the PCI
  // address port is added to the data port address.
  value.access_size = 2;
  value.u16 = 0;
  bus.set_config_addr(pci_type1_addr(0, 0, 0, PCI_CONFIG_DEVICE_ID));
  // Verify we're using a 4b aligned register address.
  EXPECT_EQ(bus.config_addr() & bit_mask<uint32_t>(2), 0u);
  // Add the register offset to the data port base address.
  EXPECT_EQ(bus.ReadIoPort(kPciConfigDataPortBase + (PCI_CONFIG_DEVICE_ID & bit_mask<uint32_t>(2)),
                           &value),
            ZX_OK);
  EXPECT_EQ(value.access_size, 2);
  EXPECT_EQ(value.u16, PCI_DEVICE_ID_INTEL_Q35);
}

}  // namespace
