/*
 * 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 <vfs.h>
#include <kfs.h>
#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 <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, 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, 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, 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, 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, int nname)
{
	return devwalk(c, nc, name, nname, (struct dirtab *)0, 0, pcigen);
}

static int pcistat(struct chan *c, uint8_t *dp, int 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 long pciread(struct chan *c, void *va, long n, int64_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 long pciwrite(struct chan *c, void *va, long n, int64_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,
};
