/*
 * 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 <ros/memops.h>
#include <kmalloc.h>
#include <kref.h>
#include <kthread.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <err.h>
#include <pmap.h>
#include <umem.h>
#include <smp.h>
#include <net/ip.h>
#include <time.h>
#include <bitops.h>
#include <core_set.h>
#include <address_range.h>
#include <arch/ros/perfmon.h>
#include <arch/topology.h>
#include <arch/perfmon.h>
#include <arch/ros/msr-index.h>
#include <arch/msr.h>
#include <arch/devarch.h>

#define REAL_MEM_SIZE (1024 * 1024)

struct perf_context {
	struct perfmon_session *ps;
	qlock_t resp_lock;
	size_t resp_size;
	uint8_t *resp;
};

struct io_map {
	struct io_map *next;
	int reserved;
	char tag[13];
	uint32_t start;
	uint32_t end;
};

static struct {
	spinlock_t lock;
	struct io_map *map;
	struct io_map *free;
	struct io_map maps[32];				// some initial free maps
	qlock_t ql;					// lock for reading map
} iomap;

enum {
	Qdir = 0,
	Qioalloc = 1,
	Qiob,
	Qiow,
	Qiol,
	Qgdb,
	Qrealmem,
	Qmsr,
	Qperf,
	Qcstate,
	Qpstate,

	Qmax,
};

enum {
	Linelen = 31,
};

struct dev archdevtab;
static struct dirtab archdir[Qmax] = {
	{".", {Qdir, 0, QTDIR}, 0, 0555},
	{"ioalloc", {Qioalloc, 0}, 0, 0444},
	{"iob", {Qiob, 0}, 0, 0666},
	{"iow", {Qiow, 0}, 0, 0666},
	{"iol", {Qiol, 0}, 0, 0666},
	{"gdb", {Qgdb, 0}, 0, 0660},
	{"realmem", {Qrealmem, 0}, 0, 0444},
	{"msr", {Qmsr, 0}, 0, 0666},
	{"perf", {Qperf, 0}, 0, 0666},
	{"c-state", {Qcstate, 0}, 0, 0666},
	{"p-state", {Qpstate, 0}, 0, 0666},
};

/* White list entries must not overlap. */
#define MSR_MAX_VAR_COUNTERS 16
#define MSR_MAX_FIX_COUNTERS 4

static struct address_range msr_rd_wlist[] = {
	ADDRESS_RANGE(0x00000000, 0xffffffff),
};
static struct address_range msr_wr_wlist[] = {
	ADDRESS_RANGE(MSR_IA32_PERFCTR0,
				  MSR_IA32_PERFCTR0 + MSR_MAX_VAR_COUNTERS - 1),
	ADDRESS_RANGE(MSR_ARCH_PERFMON_EVENTSEL0,
				  MSR_ARCH_PERFMON_EVENTSEL0 + MSR_MAX_VAR_COUNTERS - 1),
	ADDRESS_RANGE(MSR_IA32_PERF_CTL, MSR_IA32_PERF_CTL),
	ADDRESS_RANGE(MSR_CORE_PERF_FIXED_CTR0,
				  MSR_CORE_PERF_FIXED_CTR0 + MSR_MAX_FIX_COUNTERS - 1),
	ADDRESS_RANGE(MSR_CORE_PERF_FIXED_CTR_CTRL, MSR_CORE_PERF_GLOBAL_OVF_CTRL),
	ADDRESS_RANGE(MSR_IA32_MPERF, MSR_IA32_APERF),
};
int gdbactive = 0;

//
//  alloc some io port space and remember who it was
//  alloced to.  if port < 0, find a free region.
//
int ioalloc(int port, int size, int align, char *tag)
{
	struct io_map *map, **l;
	int i;

	spin_lock(&(&iomap)->lock);
	if (port < 0) {
		// find a free port above 0x400 and below 0x1000
		port = 0x400;
		for (l = &iomap.map; *l; l = &(*l)->next) {
			map = *l;
			if (map->start < 0x400)
				continue;
			i = map->start - port;
			if (i > size)
				break;
			if (align > 0)
				port = ((port + align - 1) / align) * align;
			else
				port = map->end;
		}
		if (*l == NULL) {
			spin_unlock(&(&iomap)->lock);
			return -1;
		}
	} else {
		// Only 64KB I/O space on the x86.
		if ((port + size) > 0x10000) {
			spin_unlock(&(&iomap)->lock);
			return -1;
		}
		// see if the space clashes with previously allocated ports
		for (l = &iomap.map; *l; l = &(*l)->next) {
			map = *l;
			if (map->end <= port)
				continue;
			if (map->reserved && map->start == port && map->end == port + size) {
				map->reserved = 0;
				spin_unlock(&(&iomap)->lock);
				return map->start;
			}
			if (map->start >= port + size)
				break;
			spin_unlock(&(&iomap)->lock);
			return -1;
		}
	}
	map = iomap.free;
	if (map == NULL) {
		printd("ioalloc: out of maps");
		spin_unlock(&(&iomap)->lock);
		return port;
	}
	iomap.free = map->next;
	map->next = *l;
	map->start = port;
	map->end = port + size;
	strlcpy(map->tag, tag, sizeof(map->tag));
	*l = map;

	archdir[0].qid.vers++;

	spin_unlock(&(&iomap)->lock);
	return map->start;
}

void iofree(int port)
{
	struct io_map *map, **l;

	spin_lock(&(&iomap)->lock);
	for (l = &iomap.map; *l; l = &(*l)->next) {
		if ((*l)->start == port) {
			map = *l;
			*l = map->next;
			map->next = iomap.free;
			iomap.free = map;
			break;
		}
		if ((*l)->start > port)
			break;
	}
	archdir[0].qid.vers++;
	spin_unlock(&(&iomap)->lock);
}

int iounused(int start, int end)
{
	struct io_map *map;

	for (map = iomap.map; map; map = map->next) {
		if (((start >= map->start) && (start < map->end)) ||
		    ((start <= map->start) && (end > map->start)))
			return 0;
	}
	return 1;
}

void ioinit(void)
{
	int i;
	char *excluded = "";

	panic("Akaros doesn't do IO port allocation yet.  Don't init.");
	for (i = 0; i < ARRAY_SIZE(iomap.maps) - 1; i++)
		iomap.maps[i].next = &iomap.maps[i + 1];
	iomap.maps[i].next = NULL;
	iomap.free = iomap.maps;
	char *s;

	s = excluded;
	while (s && *s != '\0' && *s != '\n') {
		char *ends;
		int io_s, io_e;

		io_s = (int)strtol(s, &ends, 0);
		if (ends == NULL || ends == s || *ends != '-') {
			printd("ioinit: cannot parse option string\n");
			break;
		}
		s = ++ends;

		io_e = (int)strtol(s, &ends, 0);
		if (ends && *ends == ',')
			*ends++ = '\0';
		s = ends;

		ioalloc(io_s, io_e - io_s + 1, 0, "pre-allocated");
	}
}

// Reserve a range to be ioalloced later.
// This is in particular useful for exchangable cards, such
// as pcmcia and cardbus cards.
int ioreserve(int unused_int, int size, int align, char *tag)
{
	struct io_map *map, **l;
	int i, port;

	spin_lock(&(&iomap)->lock);
	// find a free port above 0x400 and below 0x1000
	port = 0x400;
	for (l = &iomap.map; *l; l = &(*l)->next) {
		map = *l;
		if (map->start < 0x400)
			continue;
		i = map->start - port;
		if (i > size)
			break;
		if (align > 0)
			port = ((port + align - 1) / align) * align;
		else
			port = map->end;
	}
	if (*l == NULL) {
		spin_unlock(&(&iomap)->lock);
		return -1;
	}
	map = iomap.free;
	if (map == NULL) {
		printd("ioalloc: out of maps");
		spin_unlock(&(&iomap)->lock);
		return port;
	}
	iomap.free = map->next;
	map->next = *l;
	map->start = port;
	map->end = port + size;
	map->reserved = 1;
	strlcpy(map->tag, tag, sizeof(map->tag));
	*l = map;

	archdir[0].qid.vers++;

	spin_unlock(&(&iomap)->lock);
	return map->start;
}

static void checkport(int start, int end)
{
	/* standard vga regs are OK */
	if (start >= 0x2b0 && end <= 0x2df + 1)
		return;
	if (start >= 0x3c0 && end <= 0x3da + 1)
		return;

	if (iounused(start, end))
		return;
	error(EPERM, ERROR_FIXME);
}

static struct chan *archattach(char *spec)
{
	return devattach(archdevtab.name, spec);
}

struct walkqid *archwalk(struct chan *c, struct chan *nc, char **name,
						 unsigned int nname)
{
	return devwalk(c, nc, name, nname, archdir, Qmax, devgen);
}

static size_t archstat(struct chan *c, uint8_t *dp, size_t n)
{
	archdir[Qrealmem].length = REAL_MEM_SIZE;

	return devstat(c, dp, n, archdir, Qmax, devgen);
}

static struct perf_context *arch_create_perf_context(void)
{
	ERRSTACK(1);
	struct perf_context *pc = kzmalloc(sizeof(struct perf_context),
	                                   MEM_WAIT);

	if (waserror()) {
		kfree(pc);
		nexterror();
	}
	qlock_init(&pc->resp_lock);
	pc->ps = perfmon_create_session();
	poperror();

	return pc;
}

/* Called after the last reference (FD / chan) to pc is closed. */
static void arch_free_perf_context(struct perf_context *pc)
{
	perfmon_close_session(pc->ps);
	kfree(pc->resp);
	kfree(pc);
}

static const uint8_t *arch_read_core_set(struct core_set *cset,
                                         const uint8_t *kptr,
                                         const uint8_t *ktop)
{
	int i, nb;
	uint32_t n;

	error_assert(EBADMSG, (kptr + sizeof(uint32_t)) <= ktop);
	kptr = get_le_u32(kptr, &n);
	error_assert(EBADMSG, (kptr + n) <= ktop);
	core_set_init(cset);
	nb = MIN((int) n * 8, num_cores);
	for (i = 0; i < nb; i++) {
		if (test_bit(i, (const unsigned long *) kptr))
			core_set_setcpu(cset, i);
	}

	return kptr + n;
}

static long arch_perf_write(struct perf_context *pc, const void *udata,
                            long usize)
{
	ERRSTACK(1);
	void *kdata;
	const uint8_t *kptr, *ktop;

	kdata = user_memdup_errno(current, udata, usize);
	if (unlikely(!kdata))
		return -1;
	qlock(&pc->resp_lock);
	if (waserror()) {
		qunlock(&pc->resp_lock);
		kfree(kdata);
		nexterror();
	}
	/* Fresh command, reset the response buffer */
	kfree(pc->resp);
	pc->resp = NULL;
	pc->resp_size = 0;

	kptr = kdata;
	ktop = kptr + usize;
	error_assert(EBADMSG, (kptr + 1) <= ktop);
	switch (*kptr++) {
		case PERFMON_CMD_COUNTER_OPEN: {
			int ped;
			struct perfmon_event pev;
			struct core_set cset;

			error_assert(EBADMSG, (kptr + 3 * sizeof(uint64_t)) <= ktop);
			perfmon_init_event(&pev);
			kptr = get_le_u64(kptr, &pev.event);
			kptr = get_le_u64(kptr, &pev.flags);
			kptr = get_le_u64(kptr, &pev.trigger_count);
			kptr = get_le_u64(kptr, &pev.user_data);
			kptr = arch_read_core_set(&cset, kptr, ktop);

			ped = perfmon_open_event(&cset, pc->ps, &pev);

			pc->resp_size = sizeof(uint32_t);
			pc->resp = kmalloc(pc->resp_size, MEM_WAIT);
			put_le_u32(pc->resp, (uint32_t) ped);
			break;
		}
		case PERFMON_CMD_COUNTER_STATUS: {
			uint32_t ped;
			uint8_t *rptr;
			struct perfmon_status *pef;

			error_assert(EBADMSG, (kptr + sizeof(uint32_t)) <= ktop);
			kptr = get_le_u32(kptr, &ped);

			pef = perfmon_get_event_status(pc->ps, (int) ped);

			pc->resp_size = sizeof(uint32_t) + num_cores * sizeof(uint64_t);
			pc->resp = kmalloc(pc->resp_size, MEM_WAIT);
			rptr = put_le_u32(pc->resp, num_cores);
			for (int i = 0; i < num_cores; i++)
				rptr = put_le_u64(rptr, pef->cores_values[i]);

			perfmon_free_event_status(pef);
			break;
		}
		case PERFMON_CMD_COUNTER_CLOSE: {
			uint32_t ped;

			error_assert(EBADMSG, (kptr + sizeof(uint32_t)) <= ktop);
			kptr = get_le_u32(kptr, &ped);

			perfmon_close_event(pc->ps, (int) ped);
			break;
		}
		case PERFMON_CMD_CPU_CAPS: {
			uint8_t *rptr;
			struct perfmon_cpu_caps pcc;

			perfmon_get_cpu_caps(&pcc);

			pc->resp_size = 6 * sizeof(uint32_t);
			pc->resp = kmalloc(pc->resp_size, MEM_WAIT);

			rptr = put_le_u32(pc->resp, pcc.perfmon_version);
			rptr = put_le_u32(rptr, pcc.proc_arch_events);
			rptr = put_le_u32(rptr, pcc.bits_x_counter);
			rptr = put_le_u32(rptr, pcc.counters_x_proc);
			rptr = put_le_u32(rptr, pcc.bits_x_fix_counter);
			rptr = put_le_u32(rptr, pcc.fix_counters_x_proc);
			break;
		}
		default:
			error(EINVAL, "Invalid perfmon command: 0x%x", kptr[-1]);
	}
	poperror();
	qunlock(&pc->resp_lock);
	kfree(kdata);

	return (long) (kptr - (const uint8_t *) kdata);
}

static struct chan *archopen(struct chan *c, int omode)
{
	c = devopen(c, omode, archdir, Qmax, devgen);
	switch ((uint32_t) c->qid.path) {
		case Qperf:
			if (!perfmon_supported())
				error(ENODEV, "perf is not supported");
			assert(!c->aux);
			c->aux = arch_create_perf_context();
			break;
	}

	return c;
}

static void archclose(struct chan *c)
{
	switch ((uint32_t) c->qid.path) {
		case Qperf:
			if (c->aux) {
				arch_free_perf_context((struct perf_context *) c->aux);
				c->aux = NULL;
			}
			break;
	}
}

static size_t archread(struct chan *c, void *a, size_t n, off64_t offset)
{
	char *buf, *p;
	int err, port;
	uint64_t *values;
	uint16_t *sp;
	uint32_t *lp;
	struct io_map *map;
	struct core_set cset;
	struct msr_address msra;
	struct msr_value msrv;

	switch ((uint32_t) c->qid.path) {
		case Qdir:
			return devdirread(c, a, n, archdir, Qmax, devgen);
		case Qgdb:
			p = gdbactive ? "1" : "0";
			return readstr(offset, a, n, p);
		case Qiob:
			port = offset;
			checkport(offset, offset + n);
			for (p = a; port < offset + n; port++)
				*p++ = inb(port);
			return n;
		case Qiow:
			if (n & 1)
				error(EINVAL, ERROR_FIXME);
			checkport(offset, offset + n);
			sp = a;
			for (port = offset; port < offset + n; port += 2)
				*sp++ = inw(port);
			return n;
		case Qiol:
			if (n & 3)
				error(EINVAL, ERROR_FIXME);
			checkport(offset, offset + n);
			lp = a;
			for (port = offset; port < offset + n; port += 4)
				*lp++ = inl(port);
			return n;
		case Qioalloc:
			break;
		case Qrealmem:
			return readmem(offset, a, n, KADDR(0), REAL_MEM_SIZE);
		case Qmsr:
			if (!address_range_find(msr_rd_wlist, ARRAY_SIZE(msr_rd_wlist),
			                        (uintptr_t) offset))
				error(EPERM, "MSR 0x%x not in read whitelist", offset);
			core_set_init(&cset);
			core_set_fill_available(&cset);
			msr_set_address(&msra, (uint32_t) offset);
			values = kzmalloc(num_cores * sizeof(uint64_t),
					  MEM_WAIT);
			if (!values)
				error(ENOMEM, ERROR_FIXME);
			msr_set_values(&msrv, values, num_cores);

			err = msr_cores_read(&cset, &msra, &msrv);

			if (likely(!err)) {
				if (n >= num_cores * sizeof(uint64_t)) {
					if (!memcpy_to_user_errno(current, a, values,
					                          num_cores * sizeof(uint64_t)))
						n = num_cores * sizeof(uint64_t);
					else
						n = -1;
				} else {
					kfree(values);
					error(ERANGE, "Not enough space for MSR read");
				}
			} else {
				switch (-err) {
				case (EFAULT):
					error(-err, "read_msr() faulted on MSR 0x%x", offset);
				case (ERANGE):
					error(-err, "Not enough space for MSR read");
				};
				error(-err, "MSR read failed");
			}
			kfree(values);
			return n;
		case Qperf: {
			struct perf_context *pc = (struct perf_context *) c->aux;

			assert(pc);
			qlock(&pc->resp_lock);
			if (pc->resp && ((size_t) offset < pc->resp_size)) {
				n = MIN(n, (long) pc->resp_size - (long) offset);
				if (memcpy_to_user_errno(current, a, pc->resp + offset, n))
					n = -1;
			} else {
				n = 0;
			}
			qunlock(&pc->resp_lock);

			return n;
		case Qcstate:
			return readnum_hex(offset, a, n, get_cstate(), NUMSIZE32);
		case Qpstate:
			return readnum_hex(offset, a, n, get_pstate(), NUMSIZE32);
		}
		default:
			error(EINVAL, ERROR_FIXME);
	}

	if ((buf = kzmalloc(n, 0)) == NULL)
		error(ENOMEM, ERROR_FIXME);
	p = buf;
	n = n / Linelen;
	offset = offset / Linelen;

	switch ((uint32_t) c->qid.path) {
		case Qioalloc:
			spin_lock(&(&iomap)->lock);
			for (map = iomap.map; n > 0 && map != NULL; map = map->next) {
				if (offset-- > 0)
					continue;
				snprintf(p, n * Linelen, "%#8p %#8p %-12.12s\n", map->start,
				         map->end - 1, map->tag);
				p += Linelen;
				n--;
			}
			spin_unlock(&(&iomap)->lock);
			break;
	}

	n = p - buf;
	memmove(a, buf, n);
	kfree(buf);

	return n;
}

static ssize_t cstate_write(void *ubuf, size_t len, off64_t off)
{
	set_cstate(strtoul_from_ubuf(ubuf, len, off));
	/* Poke the other cores so they use the new C-state. */
	send_broadcast_ipi(I_POKE_CORE);
	return len;
}

static void __smp_set_pstate(void *arg)
{
	unsigned int val = (unsigned int)(unsigned long)arg;

	set_pstate(val);
}

static ssize_t pstate_write(void *ubuf, size_t len, off64_t off)
{
	struct core_set all_cores;

	core_set_init(&all_cores);
	core_set_fill_available(&all_cores);
	smp_do_in_cores(&all_cores, __smp_set_pstate,
	                (void*)strtoul_from_ubuf(ubuf, len, off));
	return len;
}

static size_t archwrite(struct chan *c, void *a, size_t n, off64_t offset)
{
	char *p;
	int port, err;
	uint64_t value;
	uint16_t *sp;
	uint32_t *lp;
	struct core_set cset;
	struct msr_address msra;
	struct msr_value msrv;

	switch ((uint32_t) c->qid.path) {
		case Qgdb:
			p = a;
			if (n != 1)
				error(EINVAL, "Gdb: Write one byte, '1' or '0'");
			if (*p == '1')
				gdbactive = 1;
			else if (*p == '0')
				gdbactive = 0;
			else
				error(EINVAL, "Gdb: must be 1 or 0");
			return 1;
		case Qiob:
			p = a;
			checkport(offset, offset + n);
			for (port = offset; port < offset + n; port++)
				outb(port, *p++);
			return n;
		case Qiow:
			if (n & 1)
				error(EINVAL, ERROR_FIXME);
			checkport(offset, offset + n);
			sp = a;
			for (port = offset; port < offset + n; port += 2)
				outw(port, *sp++);
			return n;
		case Qiol:
			if (n & 3)
				error(EINVAL, ERROR_FIXME);
			checkport(offset, offset + n);
			lp = a;
			for (port = offset; port < offset + n; port += 4)
				outl(port, *lp++);
			return n;
		case Qmsr:
			if (!address_range_find(msr_wr_wlist, ARRAY_SIZE(msr_wr_wlist),
			                        (uintptr_t) offset))
				error(EPERM, "MSR 0x%x not in write whitelist", offset);
			if (n != sizeof(uint64_t))
				error(EINVAL, "Tried to write more than a u64 (%p)", n);
			if (memcpy_from_user_errno(current, &value, a, sizeof(value)))
				return -1;

			core_set_init(&cset);
			core_set_fill_available(&cset);
			msr_set_address(&msra, (uint32_t) offset);
			msr_set_value(&msrv, value);

			err = msr_cores_write(&cset, &msra, &msrv);
			if (unlikely(err)) {
				switch (-err) {
				case (EFAULT):
					error(-err, "write_msr() faulted on MSR 0x%x", offset);
				case (ERANGE):
					error(-err, "Not enough space for MSR write");
				};
				error(-err, "MSR write failed");
			}
			return sizeof(uint64_t);
		case Qperf: {
			struct perf_context *pc = (struct perf_context *) c->aux;

			assert(pc);

			return arch_perf_write(pc, a, n);
		}
		case Qcstate:
			return cstate_write(a, n, 0);
		case Qpstate:
			return pstate_write(a, n, 0);
		default:
			error(EINVAL, ERROR_FIXME);
	}
	return 0;
}

static void archinit(void)
{
	int ret;

	ret = address_range_init(msr_rd_wlist, ARRAY_SIZE(msr_rd_wlist));
	assert(!ret);
	ret = address_range_init(msr_wr_wlist, ARRAY_SIZE(msr_wr_wlist));
	assert(!ret);
}

struct dev archdevtab __devtab = {
	.name = "arch",

	.reset = devreset,
	.init = archinit,
	.shutdown = devshutdown,
	.attach = archattach,
	.walk = archwalk,
	.stat = archstat,
	.open = archopen,
	.create = devcreate,
	.close = archclose,
	.read = archread,
	.bread = devbread,
	.write = archwrite,
	.bwrite = devbwrite,
	.remove = devremove,
	.wstat = devwstat,
};

void archreset(void)
{
	int i;

	/*
	 * And sometimes there is no keyboard...
	 *
	 * The reset register (0xcf9) is usually in one of the bridge
	 * chips. The actual location and sequence could be extracted from
	 * ACPI but why bother, this is the end of the line anyway.
	 print("Takes a licking and keeps on ticking...\n");
	 */
	i = inb(0xcf9);	/* ICHx reset control */
	i &= 0x06;
	outb(0xcf9, i | 0x02);	/* SYS_RST */
	udelay(1000);
	outb(0xcf9, i | 0x06);	/* RST_CPU transition */

	udelay(100 * 1000);

	/* some broken hardware -- as well as qemu -- might
	 * never reboot anyway with cf9. This is a standard
	 * keyboard reboot sequence known to work on really
	 * broken stuff -- like qemu. If there is no
	 * keyboard it will do no harm.
	 */
	for (;;) {
		(void)inb(0x64);
		outb(0x64, 0xFE);
		udelay(100 * 1000);
	}
}
