/*
 * 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);
}

/* 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, f, datao;

	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;
	}
	if (p->msi_ready) {
		/* only allowing one enable of MSI per device (not supporting
		 * multiple vectors) */
		printk("MSI: MSI is already enabled, aborting\n");
		spin_unlock_irqsave(&p->lock);
		return -1;
	}
	p->msi_ready = TRUE;

	/* 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;
	}

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

	if (msi_blacklist(p) != 0) {
		spin_unlock_irqsave(&p->lock);
		return -1;
	}

	/* Data begins at 8 bytes in. */
	datao = 8;
	p->msi_msg_addr_lo = msi_make_addr_lo(vec);
	printd("Write to %d %08lx \n",c + 4, p->msi_msg_addr_lo);
	pcidev_write32(p, c + 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, c + 8, 0);
	}
	p->msi_msg_addr_hi = 0;

	p->msi_msg_data = msi_make_data(vec);
	printd("Write data %d %04x\n", c + datao, p->msi_msg_data);
	pcidev_write16(p, c + 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, c + 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. */
	printd("write @ %d %04lx\n",c + 2, f);
	pcidev_write16(p, c + 2, f);
	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;
}

/* 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_mask_entry(entry);
		write_mmreg32((uintptr_t)&entry->data, 0);
	}
	/* 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_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);
}
