/* Copyright (c) 2009, 2010 The Regents of the University of California
 * See LICENSE for details.
 *
 * Barret Rhoden <brho@cs.berkeley.edu>
 * Original by Paul Pearce <pearce@eecs.berkeley.edu> */

#include <arch/x86.h>
#include <arch/pci.h>
#include <arch/intel-iommu.h>
#include <trap.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <kmalloc.h>
#include <mm.h>
#include <arch/pci_defs.h>
#include <ros/errno.h>
#include <acpi.h>
#include <process.h>

/* List of all discovered devices */
struct pcidev_stailq pci_devices = STAILQ_HEAD_INITIALIZER(pci_devices);

/* PCI accesses are two-stage PIO, which need to complete atomically */
spinlock_t pci_lock = SPINLOCK_INITIALIZER_IRQSAVE;

static char STD_PCI_DEV[] = "Standard PCI Device";
static char PCI2PCI[] = "PCI-to-PCI Bridge";
static char PCI2CARDBUS[] = "PCI-Cardbus Bridge";

static uint32_t pci_cfg_pio_read32(uint8_t bus, uint8_t dev, uint8_t func,
				   uint32_t offset);

/* Gets any old raw bar, with some catches based on type. */
static uint32_t pci_getbar(struct pci_device *pcidev, unsigned int bar)
{
	uint8_t type;

	if (bar >= MAX_PCI_BAR)
		panic("Nonexistant bar requested!");
	type = pcidev_read8(pcidev, PCI_HEADER_REG);
	type &= ~0x80;	/* drop the MF bit */
	/* Only types 0 and 1 have BARS */
	if ((type != 0x00) && (type != 0x01))
		return 0;
	/* Only type 0 has BAR2 - BAR5 */
	if ((bar > 1) && (type != 0x00))
		return 0;
	return pcidev_read32(pcidev, PCI_BAR0_STD + bar * PCI_BAR_OFF);
}

/* Determines if a given bar is IO (o/w, it's mem) */
static bool pci_is_iobar(uint32_t bar)
{
	return bar & PCI_BAR_IO;
}

static bool pci_is_membar32(uint32_t bar)
{
	if (pci_is_iobar(bar))
		return FALSE;
	return (bar & PCI_MEMBAR_TYPE) == PCI_MEMBAR_32BIT;
}

static bool pci_is_membar64(uint32_t bar)
{
	if (pci_is_iobar(bar))
		return FALSE;
	return (bar & PCI_MEMBAR_TYPE) == PCI_MEMBAR_64BIT;
}

/* Helper to get the address from a membar.  Check the type beforehand */
static uint32_t pci_getmembar32(uint32_t bar)
{
	uint8_t type = bar & PCI_MEMBAR_TYPE;

	if (type != PCI_MEMBAR_32BIT) {
		warn("Unhandled PCI membar type: %02p\n", type >> 1);
		return 0;
	}
	return bar & 0xfffffff0;
}

/* Helper to get the address from an IObar.  Check the type beforehand */
static uint32_t pci_getiobar32(uint32_t bar)
{
	return bar & 0xfffffffc;
}

/* memory bars have a little dance you go through to detect what the size of the
 * memory region is.  for 64 bit bars, i'm assuming you only need to do this to
 * the lower part (no device will need > 4GB, right?).
 *
 * Hold the dev's lock, or o/w avoid sync issues. */
static uint32_t __pci_membar_get_sz(struct pci_device *pcidev, int bar)
{
	/* save the old value, write all 1s, invert, add 1, restore.
	 * http://wiki.osdev.org/PCI for details. */
	uint32_t bar_off = PCI_BAR0_STD + bar * PCI_BAR_OFF;
	uint32_t old_val = pcidev_read32(pcidev, bar_off);
	uint32_t retval;

	pcidev_write32(pcidev, bar_off, 0xffffffff);
	/* Don't forget to mask the lower 3 bits! */
	retval = pcidev_read32(pcidev, bar_off) & PCI_BAR_MEM_MASK;
	retval = ~retval + 1;
	pcidev_write32(pcidev, bar_off, old_val);
	return retval;
}

/* process the bars.  these will tell us what address space (PIO or memory) and
 * where the base is.  fills results into pcidev.  i don't know if you can have
 * multiple bars with conflicting/different regions (like two separate PIO
 * ranges).  I'm assuming you don't, and will warn if we see one. */
static void __pci_handle_bars(struct pci_device *pcidev)
{
	uint32_t bar_val;
	int max_bars;

	if (pcidev->header_type == STD_PCI_DEV)
		max_bars = MAX_PCI_BAR;
	else if (pcidev->header_type == PCI2PCI)
		max_bars = 2;
	else
		max_bars = 0;
	/* TODO: consider aborting for classes 00, 05 (memory ctlr), 06 (bridge)
	 */
	for (int i = 0; i < max_bars; i++) {
		bar_val = pci_getbar(pcidev, i);
		pcidev->bar[i].raw_bar = bar_val;
		if (!bar_val)	/* (0 denotes no valid data) */
			continue;
		if (pci_is_iobar(bar_val)) {
			pcidev->bar[i].pio_base = pci_getiobar32(bar_val);
		} else {
			if (pci_is_membar32(bar_val)) {
				pcidev->bar[i].mmio_base32 =
					bar_val & PCI_BAR_MEM_MASK;
				pcidev->bar[i].mmio_sz =
					__pci_membar_get_sz(pcidev, i);
				pcidev->bar[i].mmio_kva =
					(void*)vmap_pmem_nocache(
						pcidev->bar[i].mmio_base32,
						pcidev->bar[i].mmio_sz);
			} else if (pci_is_membar64(bar_val)) {
				/* 64 bit, the lower 32 are in this bar, the
				 * upper are in the next bar */
				pcidev->bar[i].mmio_base64 =
					bar_val & PCI_BAR_MEM_MASK;
				assert(i < max_bars - 1);
				/* read next bar */
				bar_val = pci_getbar(pcidev, i + 1);
				/* note we don't check for IO or memsize.  the
				 * entire next bar is supposed to be for the
				 * upper 32 bits. */
				pcidev->bar[i].mmio_base64 |=
					(uint64_t)bar_val << 32;
				pcidev->bar[i].mmio_sz =
					__pci_membar_get_sz(pcidev, i);
				pcidev->bar[i].mmio_kva =
					(void*)vmap_pmem_nocache(
						pcidev->bar[i].mmio_base64,
						pcidev->bar[i].mmio_sz);
				i++;
			}
		}
		/* this will track the maximum bar we've had.  it'll include the
		 * 64 bit uppers, as well as devices that have only higher
		 * numbered bars. */
		pcidev->nr_bars = i + 1;
	}
}

static void __pci_parse_caps(struct pci_device *pcidev)
{
	uint32_t cap_off;	/* not sure if this can be extended from u8 */
	uint8_t cap_id;

	if (!(pcidev_read16(pcidev, PCI_STATUS_REG) & (1 << 4)))
		return;
	switch (pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7f) {
	case 0:				/* etc */
	case 1:				/* pci to pci bridge */
		cap_off = 0x34;
		break;
	case 2:				/* cardbus bridge */
		cap_off = 0x14;
		break;
	default:
		return;
	}
	/* initial offset points to the addr of the first cap */
	cap_off = pcidev_read8(pcidev, cap_off);
	cap_off &= ~0x3;	/* osdev says the lower 2 bits are reserved */
	while (cap_off) {
		cap_id = pcidev_read8(pcidev, cap_off);
		if (cap_id > PCI_CAP_ID_MAX) {
			printk("PCI %x:%x:%x had bad cap 0x%x\n", pcidev->bus,
			       pcidev->dev, pcidev->func, cap_id);
			return;
		}
		pcidev->caps[cap_id] = cap_off;
		cap_off = pcidev_read8(pcidev, cap_off + 1);
		/* not sure if subsequent caps must be aligned or not */
		if (cap_off & 0x3)
			printk("PCI %x:%x:%x had unaligned cap offset 0x%x\n",
			       pcidev->bus, pcidev->dev, pcidev->func, cap_off);
	}
}

static uintptr_t pci_get_mmio_cfg(struct pci_device *pcidev)
{
	physaddr_t paddr;

	paddr = acpi_pci_get_mmio_cfg_addr(pcidev->domain,
					  pcidev->bus, pcidev->dev,
					  pcidev->func);
	if (!paddr)
		return 0;
	return vmap_pmem_nocache(paddr, 4096);
}

/* Scans the PCI bus.  Won't actually work for anything other than bus 0, til we
 * sort out how to handle bridge devices. */
void pci_init(void)
{
	uint32_t result = 0;
	uint16_t dev_id, ven_id;
	struct pci_device *pcidev;
	int max_nr_func;
	/* In earlier days bus address 0xff caused problems so we only iterated
	 * to PCI_MAX_BUS - 1, but this should no longer be an issue.  Old
	 * comment: phantoms at 0xff */
	for (int i = 0; i < PCI_MAX_BUS; i++) {
		for (int j = 0; j < PCI_MAX_DEV; j++) {
			max_nr_func = 1;
			for (int k = 0; k < max_nr_func; k++) {
				result = pci_cfg_pio_read32(i, j, k,
							    PCI_DEV_VEND_REG);
				dev_id = result >> 16;
				ven_id = result & 0xffff;
				/* Skip invalid IDs (not a device)
				 * If the first function doesn't exist then no
				 * device is connected, but there can be gaps in
				 * the other function numbers. Eg. 0,2,3 is ok.
				 * */
				if (ven_id == INVALID_VENDOR_ID) {
					if (k == 0)
						break;
					continue;
				}
				pcidev = kzmalloc(sizeof(struct pci_device),
						  MEM_WAIT);
				pcidev->state = DEV_STATE_UNKNOWN;
				/* we don't need to lock it til we post the
				 * pcidev to the list*/
				spinlock_init_irqsave(&pcidev->lock);
				qlock_init(&pcidev->qlock);
				/* we only discover domain 0 during legacy
				 * PCI enumeration */
				pcidev->domain = 0;
				pcidev->bus = i;
				pcidev->dev = j;
				pcidev->func = k;
				snprintf(pcidev->name, sizeof(pcidev->name),
					 "%02x:%02x.%x", pcidev->bus,
					 pcidev->dev, pcidev->func);
				pcidev->dev_id = dev_id;
				pcidev->ven_id = ven_id;
				/* Set up the MMIO CFG before using accessors */
				pcidev->mmio_cfg = pci_get_mmio_cfg(pcidev);
				/* Get the Class/subclass */
				pcidev->class =
					pcidev_read8(pcidev, PCI_CLASS_REG);
				pcidev->subclass =
					pcidev_read8(pcidev, PCI_SUBCLASS_REG);
				pcidev->progif =
					pcidev_read8(pcidev, PCI_PROGIF_REG);
				/* All device types (0, 1, 2) have the IRQ in
				 * the same place */
				/* This is the PIC IRQ the device is wired to */
				pcidev->irqline =
					pcidev_read8(pcidev, PCI_IRQLINE_STD);
				/* This is the interrupt pin the device uses
				 * (INTA# - INTD#) */
				pcidev->irqpin =
					pcidev_read8(pcidev, PCI_IRQPIN_STD);
				/* bottom 7 bits are header type */
				switch (pcidev_read8(pcidev, PCI_HEADER_REG)
					& 0x7c) {
				case 0x00:
					pcidev->header_type = STD_PCI_DEV;
					break;
				case 0x01:
					pcidev->header_type = PCI2PCI;
					break;
				case 0x02:
					pcidev->header_type = PCI2CARDBUS;
					break;
				default:
					pcidev->header_type =
						"Unknown Header Type";
				}
				
				__pci_handle_bars(pcidev);
				__pci_parse_caps(pcidev);
				/* we're the only writer at this point in the
				 * boot process */
				STAILQ_INSERT_TAIL(&pci_devices, pcidev,
						   all_dev);
				#ifdef CONFIG_PCI_VERBOSE
				pcidev_print_info(pcidev, 4);
				#else
				pcidev_print_info(pcidev, 0);
				#endif /* CONFIG_PCI_VERBOSE */
				/* Top bit determines if we have multiple
				 * functions on this device.  We can't just
				 * check for more functions, since
				 * non-multifunction devices exist that respond
				 * to different functions with the same
				 * underlying device (same bars etc).  Note that
				 * this style allows for devices that only
				 * report multifunction in the first function's
				 * header. */
				if (pcidev_read8(pcidev, PCI_HEADER_REG) & 0x80)
					max_nr_func = PCI_MAX_FUNC;
				pcidev->proc_owner = NULL;
			}
		}
	}
	iommu_map_pci_devices();
}

uint32_t pci_config_addr(uint8_t bus, uint8_t dev, uint8_t func, uint32_t reg)
{
	return (uint32_t)(((uint32_t)bus << 16) |
	                  ((uint32_t)dev << 11) |
	                  ((uint32_t)func << 8) |
	                  (reg & 0xfc) |
	                  ((reg & 0xf00) << 16) |/* extended PCI CFG space... */
	                  0x80000000);
}

/* Helper to read 32 bits from the config space of B:D:F.  'Offset' is how far
 * into the config space we offset before reading, aka: where we are reading. */
static uint32_t pci_cfg_pio_read32(uint8_t bus, uint8_t dev, uint8_t func,
				   uint32_t offset)
{
	uint32_t ret;

	spin_lock_irqsave(&pci_lock);
	outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
	ret = inl(PCI_CONFIG_DATA);
	spin_unlock_irqsave(&pci_lock);
	return ret;
}

/* Same, but writes (doing 32bit at a time).  Never actually tested (not sure if
 * PCI lets you write back). */
static void pci_cfg_pio_write32(uint8_t bus, uint8_t dev, uint8_t func,
				uint32_t offset, uint32_t value)
{
	spin_lock_irqsave(&pci_lock);
	outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
	outl(PCI_CONFIG_DATA, value);
	spin_unlock_irqsave(&pci_lock);
}

static uint16_t pci_cfg_pio_read16(uint8_t bus, uint8_t dev, uint8_t func,
				   uint32_t offset)
{
	uint16_t ret;

	spin_lock_irqsave(&pci_lock);
	outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
	ret = inw(PCI_CONFIG_DATA + (offset & 2));
	spin_unlock_irqsave(&pci_lock);
	return ret;
}

static void pci_cfg_pio_write16(uint8_t bus, uint8_t dev, uint8_t func,
				uint32_t offset, uint16_t value)
{
	spin_lock_irqsave(&pci_lock);
	outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
	outw(PCI_CONFIG_DATA + (offset & 2), value);
	spin_unlock_irqsave(&pci_lock);
}

static uint8_t pci_cfg_pio_read8(uint8_t bus, uint8_t dev, uint8_t func,
				 uint32_t offset)
{
	uint8_t ret;

	spin_lock_irqsave(&pci_lock);
	outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
	ret = inb(PCI_CONFIG_DATA + (offset & 3));
	spin_unlock_irqsave(&pci_lock);
	return ret;
}

static void pci_cfg_pio_write8(uint8_t bus, uint8_t dev, uint8_t func,
			       uint32_t offset, uint8_t value)
{
	spin_lock_irqsave(&pci_lock);
	outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
	outb(PCI_CONFIG_DATA + (offset & 3), value);
	spin_unlock_irqsave(&pci_lock);
}

/* Some AMD processors require using eax for MMIO config ops. */
static uint32_t pci_cfg_mmio_read32(uintptr_t mmio_cfg, uint32_t offset)
{
	uint32_t val;

	asm volatile("movl (%1),%0" : "=a"(val) : "g"(mmio_cfg + offset));
	return val;
}

static void pci_cfg_mmio_write32(uintptr_t mmio_cfg, uint32_t offset,
				 uint32_t val)
{
	asm volatile("movl %0,(%1)" : : "a"(val), "g"(mmio_cfg + offset));
}

static uint16_t pci_cfg_mmio_read16(uintptr_t mmio_cfg, uint32_t offset)
{
	uint16_t val;

	asm volatile("movw (%1),%0" : "=a"(val) : "g"(mmio_cfg + offset));
	return val;
}

static void pci_cfg_mmio_write16(uintptr_t mmio_cfg, uint32_t offset,
				 uint16_t val)
{
	asm volatile("movw %0,(%1)" : : "a"(val), "g"(mmio_cfg + offset));
}

static uint8_t pci_cfg_mmio_read8(uintptr_t mmio_cfg, uint32_t offset)
{
	uint8_t val;

	asm volatile("movb (%1),%0" : "=a"(val) : "g"(mmio_cfg + offset));
	return val;
}

static void pci_cfg_mmio_write8(uintptr_t mmio_cfg, uint32_t offset,
				uint8_t val)
{
	asm volatile("movb %0,(%1)" : : "a"(val), "g"(mmio_cfg + offset));
}

uint32_t pcidev_read32(struct pci_device *pcidev, uint32_t offset)
{
	if (pcidev->mmio_cfg)
		return pci_cfg_mmio_read32(pcidev->mmio_cfg, offset);
	else
		return pci_cfg_pio_read32(pcidev->bus, pcidev->dev,
					  pcidev->func, offset);
}

void pcidev_write32(struct pci_device *pcidev, uint32_t offset, uint32_t value)
{
	if (pcidev->mmio_cfg)
		pci_cfg_mmio_write32(pcidev->mmio_cfg, offset, value);
	else
		pci_cfg_pio_write32(pcidev->bus, pcidev->dev, pcidev->func,
				    offset, value);
}

uint16_t pcidev_read16(struct pci_device *pcidev, uint32_t offset)
{
	if (pcidev->mmio_cfg)
		return pci_cfg_mmio_read16(pcidev->mmio_cfg, offset);
	else
		return pci_cfg_pio_read16(pcidev->bus, pcidev->dev,
					  pcidev->func, offset);
}

void pcidev_write16(struct pci_device *pcidev, uint32_t offset, uint16_t value)
{
	if (pcidev->mmio_cfg)
		pci_cfg_mmio_write16(pcidev->mmio_cfg, offset, value);
	else
		pci_cfg_pio_write16(pcidev->bus, pcidev->dev, pcidev->func,
				    offset, value);
}

uint8_t pcidev_read8(struct pci_device *pcidev, uint32_t offset)
{
	if (pcidev->mmio_cfg)
		return pci_cfg_mmio_read8(pcidev->mmio_cfg, offset);
	else
		return pci_cfg_pio_read8(pcidev->bus, pcidev->dev, pcidev->func,
					 offset);
}

void pcidev_write8(struct pci_device *pcidev, uint32_t offset, uint8_t value)
{
	if (pcidev->mmio_cfg)
		pci_cfg_mmio_write8(pcidev->mmio_cfg, offset, value);
	else
		pci_cfg_pio_write8(pcidev->bus, pcidev->dev, pcidev->func,
				   offset, value);
}

/* Helper to get the class description strings.  Adapted from
 * http://www.pcidatabase.com/reports.php?type=c-header */
static void pcidev_get_cldesc(struct pci_device *pcidev, char **class,
                              char **subclass, char **progif)
{
	int i;
	*class = *subclass = *progif = "";

	for (i = 0; i < PCI_CLASSCODETABLE_LEN; i++) {
		if (PciClassCodeTable[i].BaseClass == pcidev->class) {
			if (!(**class))
				*class = PciClassCodeTable[i].BaseDesc;
			if (PciClassCodeTable[i].SubClass == pcidev->subclass) {
				if (!(**subclass))
					*subclass =
						PciClassCodeTable[i].SubDesc;
				if (PciClassCodeTable[i].ProgIf ==
				    pcidev->progif) {
					*progif = PciClassCodeTable[i].ProgDesc;
					break ;
				}
			}
		}
	}
}

/* Helper to get the vendor and device description strings */
static void pcidev_get_devdesc(struct pci_device *pcidev, char **vend_short,
                               char **vend_full, char **chip, char **chip_desc)
{
	int i;
	*vend_short = *vend_full = *chip = *chip_desc = "";

	for (i = 0; i < PCI_VENTABLE_LEN; i++) {
		if (PciVenTable[i].VenId == pcidev->ven_id) {
			*vend_short = PciVenTable[i].VenShort;
			*vend_full = PciVenTable[i].VenFull;
			break ;
		}
	}
	for (i = 0; i < PCI_DEVTABLE_LEN; i++) {
		if ((PciDevTable[i].VenId == pcidev->ven_id) &&
		   (PciDevTable[i].DevId == pcidev->dev_id)) {
			*chip = PciDevTable[i].Chip;
			*chip_desc = PciDevTable[i].ChipDesc;
			break ;
		}
	}
}

/* Prints info (like lspci) for a device */
void pcidev_print_info(struct pci_device *pcidev, int verbosity)
{
	char *ven_sht, *ven_fl, *chip, *chip_txt, *class, *subcl, *progif;

	pcidev_get_cldesc(pcidev, &class, &subcl, &progif);
	pcidev_get_devdesc(pcidev, &ven_sht, &ven_fl, &chip, &chip_txt);

	printk("%02x:%02x.%x %s: %s %s %s: %s\n",
	       pcidev->bus,
	       pcidev->dev,
	       pcidev->func,
	       subcl,
	       ven_sht,
	       chip,
	       chip_txt,
		   pcidev->header_type);
	if (verbosity < 1)	/* whatever */
		return;
	printk("\tIRQ: %02d IRQ pin: 0x%02x\n",
	       pcidev->irqline,
	       pcidev->irqpin);
	printk("\tVendor Id: 0x%04x Device Id: 0x%04x\n",
	       pcidev->ven_id,
	       pcidev->dev_id);
	printk("\t%s %s %s\n",
	       class,
	       progif,
	       ven_fl);
	for (int i = 0; i < pcidev->nr_bars; i++) {
		if (pcidev->bar[i].raw_bar == 0)
			continue;
		printk("\tBAR %d: ", i);
		if (pci_is_iobar(pcidev->bar[i].raw_bar)) {
			assert(pcidev->bar[i].pio_base);
			printk("IO port 0x%04x\n", pcidev->bar[i].pio_base);
		} else {
			bool bar_is_64 =
				pci_is_membar64(pcidev->bar[i].raw_bar);
			printk("MMIO Base%s %p, MMIO Size %p\n",
			       bar_is_64 ? "64" : "32",
			       bar_is_64 ? pcidev->bar[i].mmio_base64 :
			                   pcidev->bar[i].mmio_base32,
			       pcidev->bar[i].mmio_sz);
			/* Takes up two bars */
			if (bar_is_64) {
				assert(!pcidev->bar[i].mmio_base32);
				i++;
			}
		}
	}
	printk("\tCapabilities:");
	for (int i = 0; i < PCI_CAP_ID_MAX + 1; i++) {
		if (pcidev->caps[i])
			printk(" 0x%02x", i);
	}
	printk("\n");
}

void pci_set_bus_master(struct pci_device *pcidev)
{
	spin_lock_irqsave(&pcidev->lock);
	pcidev_write16(pcidev, PCI_CMD_REG, pcidev_read16(pcidev, PCI_CMD_REG) |
	                                    PCI_CMD_BUS_MAS);
	spin_unlock_irqsave(&pcidev->lock);
}

void pci_clr_bus_master(struct pci_device *pcidev)
{
	uint16_t reg;

	spin_lock_irqsave(&pcidev->lock);
	reg = pcidev_read16(pcidev, PCI_CMD_REG);
	reg &= ~PCI_CMD_BUS_MAS;
	pcidev_write16(pcidev, PCI_CMD_REG, reg);
	spin_unlock_irqsave(&pcidev->lock);
}

static struct pci_device *pci_match_bus_dev_func(int bus, int dev, int func)
{
	struct pci_device *search;

	STAILQ_FOREACH(search, &pci_devices, all_dev) {
		if ((search->bus == bus) &&
		    (search->dev == dev) &&
		    (search->func == func))
			return search;
	}
	return NULL;
}

struct pci_device *pci_match_tbdf(int tbdf)
{
	return pci_match_bus_dev_func(BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf));
}

/* Throws on error */
struct pci_device *pci_match_string(const char *bdf)
{
	struct pci_device *pdev;
	int bus, dev, func, ret;

	ret = sscanf(bdf, "%x:%x.%x", &bus, &dev, &func);
	if (ret != 3)
		error(EINVAL, "Bad BDF format %s", bdf);
	if ((bus != (bus & 0xff)) ||
	    (dev != (dev & 0x1f)) ||
	    (func != (func & 0x07)))
		error(EINVAL, "BDF %s out of range", bdf);
	pdev = pci_match_tbdf(MKBUS(BusPCI, bus, dev, func));
	if (!pdev)
		error(ENOENT, "No BDF %s", bdf);
	return pdev;
}

/* Helper to get the membar value for BAR index bir */
uintptr_t pci_get_membar(struct pci_device *pcidev, int bir)
{
	if (bir >= pcidev->nr_bars)
		return 0;
	if (pcidev->bar[bir].mmio_base64) {
		assert(pci_is_membar64(pcidev->bar[bir].raw_bar));
		return pcidev->bar[bir].mmio_base64;
	}
	/* we can just return mmio_base32, even if it's 0.  but i'd like to do
	 * the assert too. */
	if (pcidev->bar[bir].mmio_base32) {
		assert(pci_is_membar32(pcidev->bar[bir].raw_bar));
		return pcidev->bar[bir].mmio_base32;
	}
	return 0;
}

uintptr_t pci_get_iobar(struct pci_device *pcidev, int bir)
{
	if (bir >= pcidev->nr_bars)
		return 0;
	/* we can just return pio_base, even if it's 0.  but i'd like to do the
	 * assert too. */
	if (pcidev->bar[bir].pio_base) {
		assert(pci_is_iobar(pcidev->bar[bir].raw_bar));
		return pcidev->bar[bir].pio_base;
	}
	return 0;
}

bool pci_bar_is_mem32(struct pci_device *pdev, int bir)
{
	if (bir >= pdev->nr_bars)
		return false;
	return pci_is_membar32(pdev->bar[bir].raw_bar);
}

uint32_t pci_get_membar_sz(struct pci_device *pcidev, int bir)
{
	if (bir >= pcidev->nr_bars)
		return 0;
	return pcidev->bar[bir].mmio_sz;
}

uint16_t pci_get_vendor(struct pci_device *pcidev)
{
	return pcidev->ven_id;
}

uint16_t pci_get_device(struct pci_device *pcidev)
{
	return pcidev->dev_id;
}

uint16_t pci_get_subvendor(struct pci_device *pcidev)
{
	uint8_t header_type = pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7c;

	switch (header_type) {
	case 0x00: /* STD_PCI_DEV */
		return pcidev_read16(pcidev, PCI_SUBSYSVEN_STD);
	case 0x01: /* PCI2PCI */
		return -1;
	case 0x02: /* PCI2CARDBUS */
		return pcidev_read16(pcidev, PCI_SUBVENID_CB);
	default:
		warn("Unknown Header Type, %d", header_type);
	}
	return -1;
}

uint16_t pci_get_subdevice(struct pci_device *pcidev)
{
	uint8_t header_type = pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7c;

	switch (header_type) {
	case 0x00: /* STD_PCI_DEV */
		return pcidev_read16(pcidev, PCI_SUBSYSID_STD);
	case 0x01: /* PCI2PCI */
		return -1;
	case 0x02: /* PCI2CARDBUS */
		return pcidev_read16(pcidev, PCI_SUBDEVID_CB);
	default:
		warn("Unknown Header Type, %d", header_type);
	}
	return -1;
}

void pci_dump_config(struct pci_device *pcidev, size_t len)
{
	if (len > 256)
		printk("FYI, printing more than 256 bytes of PCI space\n");
	printk("PCI Config space for %02x:%02x:%02x\n---------------------\n",
	       pcidev->bus, pcidev->dev, pcidev->func);
	for (int i = 0; i < len; i += 4)
		printk("0x%03x | %08x\n", i, pcidev_read32(pcidev, i));
}

int pci_find_cap(struct pci_device *pcidev, uint8_t cap_id, uint32_t *cap_reg)
{
	if (cap_id > PCI_CAP_ID_MAX)
		return -EINVAL;
	if (!pcidev->caps[cap_id])
		return -ENOENT;
	/* The actual value at caps[id] is the offset in the PCI config space
	 * where that ID was stored.  That's needed for accessing the
	 * capability. */
	if (cap_reg)
		*cap_reg = pcidev->caps[cap_id];
	return 0;
}

unsigned int pci_to_tbdf(struct pci_device *pcidev)
{
	return MKBUS(BusPCI, pcidev->bus, pcidev->dev, pcidev->func);
}

uintptr_t pci_map_membar(struct pci_device *dev, int bir)
{
	uintptr_t paddr = pci_get_membar(dev, bir);
	size_t sz = pci_get_membar_sz(dev, bir);
	
	if (!paddr || !sz)
		return 0;
	return vmap_pmem_nocache(paddr, sz);
}

/* The following were ported from Linux:
 *
 * pci_set_cacheline_size
 * pci_set_mwi
 * pci_clear_mwi
 */
int pci_set_cacheline_size(struct pci_device *dev)
{
	uint8_t cl_sz;
	uint8_t pci_cache_line_size = ARCH_CL_SIZE >> 2;

	cl_sz = pcidev_read8(dev, PCI_CACHE_LINE_SIZE);
	/* Validate current setting: the PCI_CACHE_LINE_SIZE must be equal to or
	 * multiple of the right value. */
	if (cl_sz >= pci_cache_line_size && (cl_sz % pci_cache_line_size) == 0)
		return 0;
	pcidev_write8(dev, PCI_CACHE_LINE_SIZE, pci_cache_line_size);
	cl_sz = pcidev_read8(dev, PCI_CACHE_LINE_SIZE);
	if (cl_sz == pci_cache_line_size)
		return 0;
	printk("PCI device %s does not support cache line size of %d\n",
	       dev->name, pci_cache_line_size << 2);
	return -EINVAL;
}

int pci_set_mwi(struct pci_device *dev)
{
	int rc;
	uint16_t cmd;

	rc = pci_set_cacheline_size(dev);
	if (rc)
		return rc;
	cmd = pcidev_read16(dev, PCI_COMMAND);
	if (!(cmd & PCI_COMMAND_INVALIDATE)) {
		cmd |= PCI_COMMAND_INVALIDATE;
		pcidev_write16(dev, PCI_COMMAND, cmd);
	}
	return 0;
}

void pci_clear_mwi(struct pci_device *dev)
{
	uint16_t cmd;

	cmd = pcidev_read16(dev, PCI_COMMAND);
	if (cmd & PCI_COMMAND_INVALIDATE) {
		cmd &= ~PCI_COMMAND_INVALIDATE;
		pcidev_write16(dev, PCI_COMMAND, cmd);
	}
}

void pci_set_ops(struct pci_device *pdev, struct pci_ops *ops, int pci_state)
{
	pdev->_ops = ops;
	assert(pdev->state == DEV_STATE_UNKNOWN);
	pdev->state = pci_state;
}

static void __pci_device_assign_check(struct pci_device *pdev)
{
	if (pdev->state != DEV_STATE_UNASSIGNED)
		error(EBUSY, "Dev %s was not unassigned (%d, %d))", pdev->name,
		      pdev->state,
		      pdev->proc_owner ? pdev->proc_owner->pid : 0);
	if (!pdev->iommu)
		error(ENODEV, "Dev %s does not have an iommu!", pdev->name);
	if (!pdev->_ops)
		error(ENODEV, "Dev %s does not have pci_ops!", pdev->name);

	if (pdev->proc_owner) {
		warn("Unassigned pdev %s has owner %d, aborting", pdev->name,
		     pdev->proc_owner->pid);
		error(EINVAL, ERROR_FIXME);
	}
}

static void __pci_device_assign_user(struct pci_device *pdev, struct proc *proc)
{
	ERRSTACK(1);
	uintptr_t prev = switch_to(proc);

	setup_dma_arena(proc);

	qlock(&proc->dev_qlock);
	qlock(&pdev->qlock);
	if (waserror()) {
		qunlock(&pdev->qlock);
		qunlock(&proc->dev_qlock);
		switch_back(proc, prev);
		nexterror();
	}
	__pci_device_assign_check(pdev);

	/* Ordering is important: iommu_device_assign() can throw */
	__iommu_device_assign(pdev, proc);
	/* Weak ref, devices get torn down synchronously during proc_destroy. */
	pdev->proc_owner = proc;

	if (!pdev->_ops->init(pdev)) {
		__iommu_device_unassign(pdev, proc);
		pdev->proc_owner = NULL;
		pdev->state = DEV_STATE_BROKEN;
		error(EFAIL, "Dev %s driver %s init failed", pdev->name,
		      pdev->_ops->driver_name);
	}

	pdev->state = DEV_STATE_ASSIGNED_USER;

	qunlock(&pdev->qlock);
	qunlock(&proc->dev_qlock);
	switch_back(proc, prev);
	poperror();
}

static void __pci_device_assign_kernel(struct pci_device *pdev)
{
	ERRSTACK(1);

	qlock(&pdev->qlock);
	if (waserror()) {
		qunlock(&pdev->qlock);
		nexterror();
	}

	__pci_device_assign_check(pdev);

	__iommu_device_assign(pdev, NULL);

	if (!pdev->_ops->init(pdev)) {
		__iommu_device_unassign(pdev, NULL);
		pdev->state = DEV_STATE_BROKEN;
		error(EFAIL, "Dev %s driver %s init failed", pdev->name,
		      pdev->_ops->driver_name);
	}

	pdev->state = DEV_STATE_ASSIGNED_KERNEL;

	qunlock(&pdev->qlock);
	poperror();
}

void pci_device_assign(struct pci_device *pdev, struct proc *proc)
{
	if (proc)
		__pci_device_assign_user(pdev, proc);
	else
		__pci_device_assign_kernel(pdev);
}

/* Unassigns a device we know is owned by proc.  Caller holds both locks and
 * handles the IOMMU. */
void pci_device_unassign_known(struct pci_device *pdev, struct proc *proc)
{
	uintptr_t prev;

	assert(proc && pdev->proc_owner == proc);

	prev = switch_to(proc);
	if (!pdev->_ops->reset(pdev))
		pdev->state = DEV_STATE_BROKEN;
	else
		pdev->state = DEV_STATE_UNASSIGNED;
	switch_back(proc, prev);

	pdev->proc_owner = NULL;

	__iommu_device_unassign(pdev, proc);
}

static void __pci_device_unassign_user(struct pci_device *pdev,
				       struct proc *proc)
{
	ERRSTACK(1);

	qlock(&proc->dev_qlock);
	qlock(&pdev->qlock);
	if (waserror()) {
		qunlock(&pdev->qlock);
		qunlock(&proc->dev_qlock);
		nexterror();
	}
	if (pdev->state != DEV_STATE_ASSIGNED_USER)
		error(EBUSY, "Dev %s was not ASSIGNED_USER (%u)", pdev->name,
		      pdev->state);
	if (pdev->proc_owner != proc)
		error(EBUSY, "Dev %s was not assigned to pid %d (%d)",
		      pdev->name, proc->pid,
		      pdev->proc_owner ? pdev->proc_owner->pid : 0);

	pci_device_unassign_known(pdev, proc);

	qunlock(&pdev->qlock);
	qunlock(&proc->dev_qlock);
	poperror();
}

static void __pci_device_unassign_kernel(struct pci_device *pdev)
{
	ERRSTACK(1);

	qlock(&pdev->qlock);
	if (waserror()) {
		qunlock(&pdev->qlock);
		nexterror();
	}
	if (pdev->state != DEV_STATE_ASSIGNED_KERNEL)
		error(EBUSY, "Dev %s was not ASSIGNED_KERNEL (%u)", pdev->name,
		      pdev->state);
	assert(!pdev->proc_owner);

	if (!pdev->_ops->reset(pdev))
		pdev->state = DEV_STATE_BROKEN;
	else
		pdev->state = DEV_STATE_UNASSIGNED;

	__iommu_device_unassign(pdev, NULL);

	qunlock(&pdev->qlock);
	poperror();
}

void pci_device_unassign(struct pci_device *pdev, struct proc *proc)
{
	if (proc)
		__pci_device_unassign_user(pdev, proc);
	else
		__pci_device_unassign_kernel(pdev);
}
