// Copyright 2018 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 <assert.h>
#include <fbl/auto_lock.h>
#include <hw/inout.h>
#include <hwreg/bitfields.h>
#include <pci/pio.h>
#include <zircon/hw/pci.h>
#include <zircon/types.h>

#ifdef __x86_64__

static constexpr uint16_t kPciConfigAddrPort = 0xCF8;
static constexpr uint16_t kPciConfigDataPort = 0xCFC;

fbl::Mutex pio_port_lock;

typedef struct {
  uint32_t value;
  DEF_SUBBIT(value, 31, enable);
  DEF_SUBFIELD(value, 23, 16, bus);
  DEF_SUBFIELD(value, 15, 11, device);
  DEF_SUBFIELD(value, 10, 8, function);
  DEF_SUBFIELD(value, 7, 0, reg_num);
} config_address_t;

// This library assumes the calling process already has the io bitmap permissions
// set to access cf8/cfc. Any processes with that permission will be synchronizing
// with each other by means of the PCI Root protocol.

static zx_status_t pci_pio_read(pci_bdf_t bdf, uint8_t offset, uint32_t* val) {
  fbl::AutoLock lock(&pio_port_lock);

  config_address_t addr = {};
  addr.set_enable(true);
  addr.set_bus(bdf.bus_id);
  addr.set_device(bdf.device_id);
  addr.set_function(bdf.function_id);
  addr.set_reg_num(offset & ~0x3);  // Lowest 2 bits must be zero, all reads are 32 bit

  outpd(kPciConfigAddrPort, addr.value);
  *val = inpd(kPciConfigDataPort);
  return ZX_OK;
}

zx_status_t pci_pio_read32(pci_bdf_t bdf, uint8_t offset, uint32_t* val) {
  // Only 32 bit alignment allowed for 32 bit reads.
  if (offset & 0x3) {
    printf("invalid args read32\n");
    return ZX_ERR_INVALID_ARGS;
  }
  uint32_t _val = 0;
  zx_status_t status = pci_pio_read(bdf, offset, val);
  if (status == ZX_OK) {
    *val = _val;
  }
  return status;
}

zx_status_t pci_pio_read16(pci_bdf_t bdf, uint8_t offset, uint16_t* val) {
  // Only 16 bit alignment allowed for 16 bit reads
  if (offset & 0x1) {
    printf("invalid args read16\n");
    return ZX_ERR_INVALID_ARGS;
  }

  uint32_t _val = 0;
  zx_status_t status = pci_pio_read(bdf, offset, &_val);
  if (status == ZX_OK) {
    // Shift the top 16 over if requested
    *val = static_cast<uint16_t>(_val >> (8u * (offset & 0x2)));
  }
  return status;
}

zx_status_t pci_pio_read8(pci_bdf_t bdf, uint8_t offset, uint8_t* val) {
  uint32_t _val = 0;
  zx_status_t status = pci_pio_read(bdf, offset, &_val);
  if (status == ZX_OK) {
    *val = static_cast<uint8_t>(_val >> (8u * (offset & 0x3)));
  }
  return status;
}

// Generates an unshifted mask to match the width of the write we're making.
static constexpr uint32_t rmw_mask(size_t width) {
  return (width == 32) ? 0xffffffff : (1u << width) - 1u;
}

// Figure out the shift to align the bytes in the right. Valid offsets are already
// checked by the pci_pio_write calls themselves.
static constexpr int calculate_shift(uint8_t offset) { return (offset & 0x3) * 8u; }

static zx_status_t pci_pio_write(pci_bdf_t bdf, uint8_t offset, uint32_t mask, uint32_t val) {
  fbl::AutoLock lock(&pio_port_lock);

  config_address_t addr = {};
  addr.set_enable(true);
  addr.set_bus(bdf.bus_id);
  addr.set_device(bdf.device_id);
  addr.set_function(bdf.function_id);
  addr.set_reg_num(offset & ~0x3);  // Lowest 3 bits must be zero, all reads are 32 bit

  outpd(kPciConfigAddrPort, addr.value);
  // Zero out the bytes we're going to write and then OR them in.
  uint32_t old_val = inpd(kPciConfigDataPort);
  old_val &= ~mask;
  old_val |= val;
  outpd(kPciConfigDataPort, old_val);

  return ZX_OK;
}

zx_status_t pci_pio_write32(pci_bdf_t bdf, uint8_t offset, uint32_t val) {
  // Only 32 bit alignment allowed for 32 bit reads
  if (offset & 0x3) {
    return ZX_ERR_INVALID_ARGS;
  }
  return pci_pio_write(bdf, offset, rmw_mask(32), val);
}

// These functions both create a shifted mask and shifted value to call the main write
// function so that its body can be as simple as possible.
zx_status_t pci_pio_write16(pci_bdf_t bdf, uint8_t offset, uint16_t val) {
  // Only 16 bit alignment allowed for 16 bit reads
  if (offset & 0x1) {
    return ZX_ERR_INVALID_ARGS;
  }
  int shift = calculate_shift(offset);
  return pci_pio_write(bdf, offset, rmw_mask(16) << shift, val << shift);
}

zx_status_t pci_pio_write8(pci_bdf_t bdf, uint8_t offset, uint8_t val) {
  int shift = calculate_shift(offset);
  return pci_pio_write(bdf, offset, rmw_mask(8) << shift, val << shift);
}

#endif  // __x86_64__
