/*
 * 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>
#include <arch/io.h>

struct dev pcidevtab;

static char *devname(void)
{
	return pcidevtab.name;
}

enum {
	Qtopdir = 0,

	Qpcidir,
	Qpcictl,
	Qpciraw,

	PCI_CONFIG_SZ = 256,
};

#define TYPE(q)		((uint32_t)(q).path & 0x0F)
#define QID(c, t)	(((c)<<4)|(t))

static struct dirtab topdir[] = {
	{".", {Qtopdir, 0, QTDIR}, 0, 0555},
	{"pci", {Qpcidir, 0, QTDIR}, 0, 0555},
};

static int pcidirgen(struct chan *c, int t, int tbdf, struct dir *dp)
{
	struct qid q;

	q = (struct qid) {
		BUSBDF(tbdf) | t, 0, 0};
	switch (t) {
	case Qpcictl:
		snprintf(get_cur_genbuf(), GENBUF_SZ, "%d.%d.%dctl",
		         BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf));
		devdir(c, q, get_cur_genbuf(), 0, eve.name, 0444, dp);
		return 1;
	case Qpciraw:
		snprintf(get_cur_genbuf(), GENBUF_SZ, "%d.%d.%draw",
		         BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf));
		devdir(c, q, get_cur_genbuf(), 128, eve.name, 0664, dp);
		return 1;
	}
	return -1;
}

static int
pcigen(struct chan *c, char *_1, struct dirtab *_2, int _3, int s,
       struct dir *dp)
{
	int tbdf;
	struct pci_device *p;
	struct qid q;

	switch (TYPE(c->qid)) {
	case Qtopdir:
		if (s == DEVDOTDOT) {
			q = (struct qid) {
				QID(0, Qtopdir), 0, QTDIR};
			snprintf(get_cur_genbuf(), GENBUF_SZ, "#%s", pcidevtab.name);
			devdir(c, q, get_cur_genbuf(), 0, eve.name, 0555, dp);
			return 1;
		}
		return devgen(c, NULL, topdir, ARRAY_SIZE(topdir), s, dp);
	case Qpcidir:
		if (s == DEVDOTDOT) {
			q = (struct qid) {
				QID(0, Qtopdir), 0, QTDIR};
			snprintf(get_cur_genbuf(), GENBUF_SZ, "#%s", pcidevtab.name);
			devdir(c, q, get_cur_genbuf(), 0, eve.name, 0555, dp);
			return 1;
		}
		STAILQ_FOREACH(p, &pci_devices, all_dev) {
			if (s < 2)
				break;
			s -= 2;
		}
		if (p == NULL)
			return -1;
		return pcidirgen(c, s + Qpcictl, pci_to_tbdf(p), dp);
	case Qpcictl:
	case Qpciraw:
		tbdf = MKBUS(BusPCI, 0, 0, 0) | BUSBDF((uint32_t) c->qid.path);
		p = pci_match_tbdf(tbdf);
		if (p == NULL)
			return -1;
		return pcidirgen(c, TYPE(c->qid), tbdf, dp);
	default:
		break;
	}
	return -1;
}

static struct chan *pciattach(char *spec)
{
	return devattach(devname(), spec);
}

struct walkqid *pciwalk(struct chan *c, struct chan *nc, char **name,
                        unsigned int nname)
{
	return devwalk(c, nc, name, nname, (struct dirtab *)0, 0, pcigen);
}

static size_t pcistat(struct chan *c, uint8_t *dp, size_t n)
{
	return devstat(c, dp, n, (struct dirtab *)0, 0L, pcigen);
}

static struct chan *pciopen(struct chan *c, int omode)
{
	c = devopen(c, omode, (struct dirtab *)0, 0, pcigen);
	switch (TYPE(c->qid)) {
	default:
		break;
	}
	return c;
}

static void pciclose(struct chan *_)
{
}

static size_t pciread(struct chan *c, void *va, size_t n, off64_t offset)
{
	char buf[PCI_CONFIG_SZ], *ebuf, *w, *a;
	int i, tbdf, r;
	uint32_t x;
	struct pci_device *p;

	a = va;
	switch (TYPE(c->qid)) {
	case Qtopdir:
	case Qpcidir:
		return devdirread(c, a, n, (struct dirtab *)0, 0L, pcigen);
	case Qpcictl:
		tbdf = MKBUS(BusPCI, 0, 0, 0) | BUSBDF((uint32_t) c->qid.path);
		p = pci_match_tbdf(tbdf);
		if (p == NULL)
			error(EINVAL, ERROR_FIXME);
		ebuf = buf + sizeof(buf) - 1;	/* -1 for newline */
		w = seprintf(buf, ebuf, "%.2x.%.2x.%.2x %.4x/%.4x %3d",
		             p->class, p->subclass, p->progif, p->ven_id, p->dev_id,
		             p->irqline);
		for (i = 0; i < COUNT_OF(p->bar); i++) {
			if (p->bar[i].mmio_sz == 0)
				continue;
			w = seprintf(w, ebuf, " %d:%.8lux %d", i, p->bar[i].pio_base,
			             p->bar[i].mmio_sz);
		}
		*w++ = '\n';
		*w = '\0';
		return readstr(offset, a, n, buf);
	case Qpciraw:
		tbdf = MKBUS(BusPCI, 0, 0, 0) | BUSBDF((uint32_t) c->qid.path);
		p = pci_match_tbdf(tbdf);
		if (p == NULL)
			error(EINVAL, ERROR_FIXME);
		if (n + offset > 256)
			n = 256 - offset;
		if (n < 0)
			return 0;
		r = offset;
		if (!(r & 3) && n == 4) {
			x = pcidev_read32(p, r);
			PBIT32(a, x);
			return 4;
		}
		if (!(r & 1) && n == 2) {
			x = pcidev_read16(p, r);
			PBIT16(a, x);
			return 2;
		}
		for (i = 0; i < n; i++) {
			x = pcidev_read8(p, r);
			PBIT8(a, x);
			a++;
			r++;
		}
		return i;
	default:
		error(EINVAL, ERROR_FIXME);
	}
	return n;
}

static size_t pciwrite(struct chan *c, void *va, size_t n, off64_t offset)
{
	uint8_t *a;
	int i, r, tbdf;
	uint32_t x;
	struct pci_device *p;

	if (n > PCI_CONFIG_SZ)
		n = PCI_CONFIG_SZ;
	a = va;

	switch (TYPE(c->qid)) {
	case Qpciraw:
		tbdf = MKBUS(BusPCI, 0, 0, 0) | BUSBDF((uint32_t) c->qid.path);
		p = pci_match_tbdf(tbdf);
		if (p == NULL)
			error(EINVAL, ERROR_FIXME);
		if (offset > PCI_CONFIG_SZ)
			return 0;
		if (n + offset > PCI_CONFIG_SZ)
			n = PCI_CONFIG_SZ - offset;
		r = offset;
		if (!(r & 3) && n == 4) {
			x = GBIT32(a);
			pcidev_write32(p, r, x);
			return 4;
		}
		if (!(r & 1) && n == 2) {
			x = GBIT16(a);
			pcidev_write16(p, r, x);
			return 2;
		}
		for (i = 0; i < n; i++) {
			x = GBIT8(a);
			pcidev_write8(p, r, x);
			a++;
			r++;
		}
		return i;
	default:
		error(EINVAL, ERROR_FIXME);
	}
	return n;
}

struct dev pcidevtab __devtab = {
	.name = "pci",

	.reset = devreset,
	.init = devinit,
	.shutdown = devshutdown,
	.attach = pciattach,
	.walk = pciwalk,
	.stat = pcistat,
	.open = pciopen,
	.create = devcreate,
	.close = pciclose,
	.read = pciread,
	.bread = devbread,
	.write = pciwrite,
	.bwrite = devbwrite,
	.remove = devremove,
	.wstat = devwstat,
};
