/*
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 */

#include <slab.h>
#include <kmalloc.h>
#include <kref.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <cpio.h>
#include <pmap.h>
#include <smp.h>
#include <net/ip.h>

enum {
	Dpcicap		= 1<<0,
	Dmsicap		= 1<<1,
	Dvec		= 1<<2,
	Debug		= 0,
};

enum {
/* MSI address format
 *
 * +31----------------------20+19----------12+11--------4+--3--+--2--+1---0+
 * |       0xfee              | Dest APIC ID |  Reserved | RH  | DM  |  XX |
 * +--------------------------+--------------+-----------+-----+-----+-----+
 *
 * RH: Redirection Hint
 * DM: Destinatio Mode
 * XX: Probably reserved, set to 0
 */
	Msiabase	= 0xfee00000u,
	Msiadest	= 1<<12,	/* same as 63:56 of apic vector */
	Msiaedest	= 1<<4,		/* same as 55:48 of apic vector */
	Msialowpri	= 1<<3,		/* redirection hint */
	Msialogical	= 1<<2,

/* MSI data format
 * +63-------------------------------------------------------------------32+
 * |                          Reserved                                     |
 * +-------------------------------+-15-+-14-+--------+10----8+7----------0+
 * |          Reserved             | TM | Lv | Reserv | Dmode |   Vector   |
 * +-------------------------------+----+----+--------+-------+------------+
 *
 * Dmode: delivery mode (like APIC/LVT messages).  Usually 000 (Fixed).
 * TM: Trigger mode (0 Edge, 1 Level)
 * Lv: Level assert (0 Deassert, 1 Assert)
 *
 *
 * for more info, check intel's SDMv3 (grep message signal) */
	Msidlevel	= 1<<15,
	Msidassert	= 1<<14,
	Msidmode	= 1<<8,		/* 3 bits; delivery mode */
	Msidvector	= 0xff<<0,
};

enum{
	/* msi capabilities */
	Vmask		= 1<<8,	/* Vectors can be masked. Optional. */
	Cap64		= 1<<7, /* 64-bit addresses. Optional. */
	Mmesgmsk	= 7<<4, /* Mask for # of messages allowed. See 6.8.1.3*/
	Mmcap		= 7<<1, /* # of messages the function can support. */
	Msienable	= 1<<0, /* Enable. */
	/* msix capabilities */
	Msixenable      = 1<<15,
	Msixmask        = 1<<14,
	Msixtblsize     = 0x7ff,
};

/* Find the offset in config space of this function of the msi capability.
 * It is defined in 6.8.1 and is variable-sized.  Returns 0 on failure. */
static int msicap(struct pci_device *p)
{
	return p->caps[PCI_CAP_ID_MSI];
}

/* Find the offset in config space of this function of the msi-x capability.
 * It is defined in 6.8.1 and is variable-sized.
 */
static int msixcap(struct pci_device *p)
{
	return p->caps[PCI_CAP_ID_MSIX];
}

static int msi_blacklist(struct pci_device *p)
{
	switch (p->ven_id << 16 | p->dev_id) {
		case 0x11ab << 16 | 0x6485:
		case 0x8086 << 16 | 0x100f:
			return -1;
	}
	return 0;
}

static int msix_blacklist(struct pci_device *p)
{
	switch (p->ven_id << 16 | p->dev_id) {
//	case 0x11ab << 16 | 0x6485:	/* placeholder */
		return -1;
	}
	return 0;
}

static uint32_t msi_make_addr_lo(uint64_t vec)
{
	unsigned int dest, lopri, logical;

	/* The destination is the traditional 8-bit APIC id is in 63:56 of the
	 * vector.  Later we may need to deal with extra destination bits
	 * (Msiaedest, in this code).  I haven't seen anything in the Intel SDM
	 * about using Msiaedest (the bits are reserved) */
	dest = vec >> 56;
	/* lopri is rarely set, and intel doesn't recommend using it.  with msi,
	 * the lopri field is actually a redirection hint, and also must be set
	 * when sending logical messages. */
	lopri = (vec & 0x700) == MTlp;
	logical = (vec & Lm) != 0;
	if (logical)
		lopri = 1;
	return Msiabase | Msiadest * dest | Msialowpri * lopri |
	       Msialogical * logical;
}

static uint32_t msi_make_data(uint64_t vec)
{
	unsigned int deliv_mode;

	deliv_mode = (vec >> 8) & 7;
	/* We can only specify the lower 16 bits of the MSI message, the rest
	 * gets forced to 0 by the device.  MSI-X can use the full 32 bits.
	 * We're assuming edge triggered here. */
	return Msidmode * deliv_mode | ((unsigned int)vec & 0xff);
}

/* TODO: do we need to be careful of reserved bits?  SDM says to preserve those
 * fields on write. */
static void __msi_set_addr_data(struct pci_device *p, int cap)
{
	unsigned int f, datao;

	/* read it, clear out the Mmesgmsk bits.
	 * This means that there will be no multiple
	 * messages enabled.
	 */
	f = pcidev_read16(p, cap + 2) & ~Mmesgmsk;

	/* Data begins at 8 bytes in. */
	datao = 8;
	pcidev_write32(p, cap + 4, p->msi_msg_addr_lo);

	/* And even if it's 64-bit capable, we do nothing with
	 * the high order bits. If it is 64-bit we need to offset
	 * datao (data offset) by 4 (i.e. another 32 bits)
	 */
	if (f & Cap64) {
		datao += 4;
		pcidev_write32(p, cap + 8, 0);
	}

	pcidev_write16(p, cap + datao, p->msi_msg_data);

	/* If we have the option of masking the vectors,
	 * blow all the masks to 0. It's a 32-bit mask.
	 */
	if (f & Vmask)
		pcidev_write32(p, cap + datao + 4, 0);

	/* Now write the control bits back, with the Mmesg mask (which is a
	 * power of 2) set to 0 (meaning one vector only).  Note we still
	 * haven't enabled MSI.  Will do that when we unmask.  According to the
	 * spec, we're not supposed to use the Msienable bit to mask the IRQ,
	 * though I don't see how we can mask on non-Vmask-supported HW. */
	pcidev_write16(p, cap + 2, f);
}

/* see section 6.8.1 of the pci spec. */
/* Set up a single function on a single device.
 * We need to take the vec, bust it up into bits,
 * and put parts of it in the msi address and parts
 * in the msi data.
 */
int pci_msi_enable(struct pci_device *p, uint64_t vec)
{
	unsigned int c;

	spin_lock_irqsave(&p->lock);
	if (p->msix_ready) {
		printk("MSI: MSI-X is already enabled, aborting\n");
		spin_unlock_irqsave(&p->lock);
		return -1;
	}
	/* msi_ready means "has an IRQ vector assigned, loaded, and masked".
	 * We're only allowing one MSI vector per device.  In comparison,
	 * msix_ready means "has all the stuff set up for MSI-X so you can get
	 * some IRQ vector, load the msix_entry, and go." */
	if (p->msi_ready) {
		printk("MSI: MSI is already enabled, aborting\n");
		spin_unlock_irqsave(&p->lock);
		return -1;
	}
	/* Get the offset of the MSI capability in the function's config space.
	 */
	c = msicap(p);
	if (!c) {
		spin_unlock_irqsave(&p->lock);
		return -1;
	}
	if (msi_blacklist(p) != 0) {
		spin_unlock_irqsave(&p->lock);
		return -1;
	}
	p->msi_msg_addr_lo = msi_make_addr_lo(vec);
	p->msi_msg_addr_hi = 0;
	p->msi_msg_data = msi_make_data(vec);
	__msi_set_addr_data(p, c);
	p->msi_ready = true;
	spin_unlock_irqsave(&p->lock);
	return 0;
}

static void __msix_mask_entry(struct msix_entry *entry)
{
	uintptr_t reg = (uintptr_t)&entry->vector;
	write_mmreg32(reg, read_mmreg32(reg) | 0x1);
}

static void __msix_unmask_entry(struct msix_entry *entry)
{
	uintptr_t reg = (uintptr_t)&entry->vector;
	write_mmreg32(reg, read_mmreg32(reg) & ~0x1);
}

static uintptr_t msix_get_capbar_paddr(struct pci_device *p, int offset)
{
	uint32_t bir, capbar_off;
	uintptr_t membar;

	bir = pcidev_read32(p, offset);
	capbar_off = bir & ~0x7;
	bir &= 0x7;
	membar = pci_get_membar(p, bir);

	if (!membar) {
		printk("MSI-X: no cap membar, bir %d\n", bir);
		return 0;
	}
	membar += capbar_off;
	return membar;
}

static void __msix_reset_entry(struct msix_entry *entry)
{
	__msix_mask_entry(entry);
	write_mmreg32((uintptr_t)&entry->data, 0);
}

/* One time initialization of MSI-X for a PCI device.  -1 on error.  Otherwise,
 * the device will be ready to assign/route MSI-X entries/vectors.  All vectors
 * are masked, but the overall MSI-X function is unmasked.
 *
 * Hold the pci_device lock. */
static int __pci_msix_init(struct pci_device *p)
{
	unsigned int c;
	uint16_t f;
	int tbl_bir, tbl_off, pba_bir, pba_off;
	struct msix_entry *entry;

	if (p->msix_ready)
		return 0;
	if (p->msi_ready) {
		printk("MSI-X: MSI is already on, aborting\n");
		return -1;
	}
	if (msix_blacklist(p) != 0)
		return -1;
	c = msixcap(p);
	if (c == 0)
		return -1;
	f = pcidev_read16(p, c + 2);
	/* enable and mask the entire function/all vectors */
	f |= Msixenable | Msixmask;
	pcidev_write16(p, c + 2, f);

	p->msix_tbl_paddr = msix_get_capbar_paddr(p, c + 4);
	p->msix_pba_paddr = msix_get_capbar_paddr(p, c + 8);
	if (!p->msix_tbl_paddr || !p->msix_pba_paddr) {
		/* disable msix, so we can possibly use msi */
		pcidev_write16(p, c + 2, f & ~Msixenable);
		printk("MSI-X: Missing a tbl (%p) or PBA (%p) paddr!\n",
		       p->msix_tbl_paddr, p->msix_pba_paddr);
		return -1;
	}
	p->msix_nr_vec = (f & Msixtblsize) + 1;
	p->msix_tbl_vaddr = vmap_pmem_nocache(p->msix_tbl_paddr,
					      p->msix_nr_vec *
	                                      sizeof(struct msix_entry));
	if (!p->msix_tbl_vaddr) {
		pcidev_write16(p, c + 2, f & ~Msixenable);
		printk("MSI-X: unable to vmap the Table!\n");
		return -1;
	}
	p->msix_pba_vaddr = vmap_pmem_nocache(p->msix_pba_paddr,
	                                      ROUNDUP(p->msix_nr_vec, 8) / 8);
	if (!p->msix_pba_vaddr) {
		pcidev_write16(p, c + 2, f & ~Msixenable);
		printk("MSI-X: unable to vmap the PBA!\n");
		vunmap_vmem(p->msix_tbl_paddr,
			    p->msix_nr_vec * sizeof(struct msix_entry));
		return -1;
	}
	/* they should all be masked already, but remasking just in case.
	 * likewise, we need to 0 out the data, since we'll use the lower byte
	 * later when determining if an msix vector is free or not. */
	entry = (struct msix_entry*)p->msix_tbl_vaddr;
	for (int i = 0; i < p->msix_nr_vec; i++, entry++)
		__msix_reset_entry(entry);
	/* unmask the device, now that all the vectors are masked */
	f &= ~Msixmask;
	pcidev_write16(p, c + 2, f);
	p->msix_ready = TRUE;
	return 0;
}

/* Some parts of msix init need to happen during boot.  Devices can call this
 * during their reset methods, and then later register their IRQs during attach.
 * Other OS's also alloc the vector around this time, though we'll hold off on
 * that for now. */
int pci_msix_init(struct pci_device *p)
{
	int ret;
	spin_lock_irqsave(&p->lock);
	ret = __pci_msix_init(p);
	spin_unlock_irqsave(&p->lock);
	return ret;
}

/* Enables an MSI-X vector for a PCI device.  vec is formatted like an ioapic
 * route.  This should be able to handle multiple vectors for a device.  Returns
 * a msix_irq_vector linkage struct on success (the connection btw an irq_h and
 * the specific {pcidev, entry}), and 0 on failure. */
struct msix_irq_vector *pci_msix_enable(struct pci_device *p, uint64_t vec)
{
	int i;
	struct msix_entry *entry;
	struct msix_irq_vector *linkage;
	unsigned int c, datao;

	spin_lock_irqsave(&p->lock);
	/* Ensure we're init'd.  We could remove this in the future, though not
	 * everyone calls the extern pci_msix_init. */
	if (__pci_msix_init(p) < 0) {
		spin_unlock_irqsave(&p->lock);
		return 0;
	}
	/* find an unused slot (no apic_vector assigned).  later, we might want
	 * to point back to the irq_hs for each entry.  not a big deal now. */
	entry = (struct msix_entry*)p->msix_tbl_vaddr;
	for (i = 0; i < p->msix_nr_vec; i++, entry++)
		if (!(read_mmreg32((uintptr_t)&entry->data) & 0xff))
			break;
	if (i == p->msix_nr_vec) {
		printk("[kernel] unable to alloc an MSI-X vector (bug?)\n");
		spin_unlock_irqsave(&p->lock);
		return 0;
	}
	linkage = kmalloc(sizeof(struct msix_irq_vector), MEM_WAIT);
	linkage->pcidev = p;
	linkage->entry = entry;
	linkage->addr_lo = msi_make_addr_lo(vec);
	linkage->addr_hi = 0;
	linkage->data = msi_make_data(vec);
	write_mmreg32((uintptr_t)&entry->data, linkage->data);
	write_mmreg32((uintptr_t)&entry->addr_lo, linkage->addr_lo);
	write_mmreg32((uintptr_t)&entry->addr_hi, linkage->addr_hi);
	spin_unlock_irqsave(&p->lock);
	return linkage;
}

void pci_dump_msix_table(struct pci_device *p)
{
	struct msix_entry *entry;
	void *tbl = (void*)p->msix_tbl_vaddr;

	hexdump(tbl, p->msix_nr_vec * sizeof(struct msix_entry));
	entry = (struct msix_entry*)p->msix_tbl_vaddr;
	for (int i = 0; i < p->msix_nr_vec; i++, entry++)
		printk("Entry %d, addr hi:lo 0x%08x:%08x data 0x%08x\n", i,
		       entry->addr_hi, entry->addr_lo, entry->data);
}

void pci_msi_mask(struct pci_device *p)
{
	unsigned int c, f;

	c = msicap(p);
	assert(c);

	spin_lock_irqsave(&p->lock);
	f = pcidev_read16(p, c + 2);
	pcidev_write16(p, c + 2, f & ~Msienable);
	spin_unlock_irqsave(&p->lock);
}

void pci_msi_unmask(struct pci_device *p)
{
	unsigned int c, f;

	c = msicap(p);
	assert(c);

	spin_lock_irqsave(&p->lock);
	f = pcidev_read16(p, c + 2);
	pcidev_write16(p, c + 2, f | Msienable);
	spin_unlock_irqsave(&p->lock);
}

void pci_msi_route(struct pci_device *p, int dest)
{
	unsigned int c, f;

	c = msicap(p);
	assert(c);

	spin_lock_irqsave(&p->lock);
	/* mask out the old destination, replace with new */
	p->msi_msg_addr_lo &= ~(((1 << 8) - 1) << 12);
	p->msi_msg_addr_lo |= (dest & 0xff) << 12;
	pcidev_write32(p, c + 4, p->msi_msg_addr_lo);
	spin_unlock_irqsave(&p->lock);
}

void pci_msi_reset_vector(struct pci_device *p)
{
	/* Might be overly paranoid.  We're clearing out any old vector set in
	 * the device. */
	spin_lock_irqsave(&p->lock);
	p->msi_msg_addr_lo = 0;
	p->msi_msg_addr_hi = 0;
	p->msi_msg_data = 0;
	__msi_set_addr_data(p, msicap(p));
	p->msi_ready = false;
	spin_unlock_irqsave(&p->lock);
}

void pci_msix_mask_vector(struct msix_irq_vector *linkage)
{
	spin_lock_irqsave(&linkage->pcidev->lock);
	__msix_mask_entry(linkage->entry);
	spin_unlock_irqsave(&linkage->pcidev->lock);
}

void pci_msix_unmask_vector(struct msix_irq_vector *linkage)
{
	spin_lock_irqsave(&linkage->pcidev->lock);
	__msix_unmask_entry(linkage->entry);
	spin_unlock_irqsave(&linkage->pcidev->lock);
}

void pci_msix_route_vector(struct msix_irq_vector *linkage, int dest)
{
	spin_lock_irqsave(&linkage->pcidev->lock);
	/* mask out the old destination, replace with new */
	linkage->addr_lo &= ~(((1 << 8) - 1) << 12);
	linkage->addr_lo |= (dest & 0xff) << 12;
	write_mmreg32((uintptr_t)&linkage->entry->addr_lo, linkage->addr_lo);
	spin_unlock_irqsave(&linkage->pcidev->lock);
}

void pci_msix_reset_vector(struct msix_irq_vector *linkage)
{
	spin_lock_irqsave(&linkage->pcidev->lock);
	__msix_reset_entry(linkage->entry);
	spin_unlock_irqsave(&linkage->pcidev->lock);
}
