/*
 * IOAPIC emulation
 *
 * Copyright 2015 Google Inc.
 *
 * See LICENSE for details.
 */

#include <parlib/stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <parlib/arch/arch.h>
#include <parlib/ros_debug.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/uio.h>
#include <stdint.h>
#include <err.h>
#include <sys/mman.h>
#include <vmm/vmm.h>
#include <vmm/virtio.h>
#include <vmm/virtio_mmio.h>
#include <vmm/virtio_ids.h>
#include <vmm/virtio_config.h>
#include <vmm/sched.h>

#define IOAPIC_CONFIG 0x100
#define IOAPIC_NUM_PINS 24

int debug_ioapic;
int apic_id_mask = 0xf0;

#define DPRINTF(fmt, ...) \
	if (debug_ioapic) { fprintf(stderr, "ioapic: " fmt , ## __VA_ARGS__); }


struct ioapic {
	int id;
	int reg;
	uint32_t arbid;
	uint32_t value[256];
};

static struct ioapic ioapic[1];

static uint32_t ioapic_read(struct guest_thread *vm_thread, int ix,
                            uint64_t offset)
{
	uint32_t ret = (uint32_t)-1;
	uint32_t reg = ioapic[ix].reg;

	if (offset == 0) {
		DPRINTF("ioapic_read ix %x return 0x%x\n", ix, reg);
		return reg;
	}

	DPRINTF("ioapic_read %x 0x%x\n", ix, (int)reg);
	switch (reg) {
	case 0:
		return ioapic[ix].id;
	case 1:
		return 0x170011;
	case 2:
		return ioapic[ix].arbid;
	default:
		if (reg >= 0 && reg < (IOAPIC_NUM_PINS*2 + 0x10)) {
			//bx_io_redirect_entry_t *entry = ioredtbl + index;
			//data = (ioregsel&1) ? entry->get_hi_part()
			//                    : entry->get_lo_part();
			ret = ioapic[ix].value[reg];
			DPRINTF("IOAPIC_READ %x: %x return %08x\n", ix, reg,
				ret);
			return ret;
		} else {
			DPRINTF("IOAPIC READ: %x BAD INDEX 0x%x\n", ix, reg);
		}
		return ret;
	}
	return 0;
}

static void ioapic_write(struct guest_thread *vm_thread, int ix,
                         uint64_t offset, uint32_t value)
{
	uint32_t ret;
	uint32_t reg = ioapic[ix].reg;
	struct virtual_machine *vm = gth_to_vm(vm_thread);
	uint32_t irqreg;

	if (offset == 0) {
		DPRINTF("ioapic_write ix %x set reg 0x%x\n", ix, value);
		ioapic[ix].reg = value;
		return;
	}

	for (int i = 0; i < VIRTIO_MMIO_MAX_NUM_DEV; i++) {
		if (vm->virtio_mmio_devices[i] == NULL)
			continue;

		/* The first IRQ register starts at 0x10, and there are two
		 * 32-bit registers for each IRQ. The first 8 bits of the value
		 * assigned to 'reg' is the interrupt vector. */
		irqreg = (vm->virtio_mmio_devices[i]->irq) * 2 + 0x10;
		if (reg == irqreg && (value & 0xff) != 0) {
			vm->virtio_mmio_devices[i]->vec = value & 0xff;
			DPRINTF("irq vector for irq number %d is: %lx\n",
			         vm->virtio_mmio_devices[i]->irq, value & 0xff);
		} else if (reg == irqreg + 1) {
			vm->virtio_mmio_devices[i]->dest = value >> 24;
			if (value >> 24 == 0xff)
				vm->virtio_mmio_devices[i]->dest = 0xffffffff;

			DPRINTF("high value for irq number %d is: %lx\n",
			         vm->virtio_mmio_devices[i]->irq, value);
			DPRINTF("irq destination for irq number %d is: %lx\n",
			         vm->virtio_mmio_devices[i]->irq, value >> 24);
		}
	}

	switch (reg) {
	case 0:
		DPRINTF("IOAPIC_WRITE: Set %d ID to %d\n", ix, value);
		ioapic[ix].id = value;
		break;
	case 1:
	case 2:
		DPRINTF("IOAPIC_WRITE: Can't write %d\n", reg);
	default:
		if (reg >= 0 && reg < (IOAPIC_NUM_PINS*2 + 0x10)) {
			ioapic[ix].value[reg] = value;
			DPRINTF("IOAPIC %x: set %08x to %016x\n", ix, reg,
				value);
		} else {
			DPRINTF("IOAPIC WRITE: %x BAD INDEX 0x%x\n", ix, reg);
		}
		break;
	}

}

int do_ioapic(struct guest_thread *vm_thread, uint64_t gpa, int destreg,
              uint64_t *regp, int store)
{
	/* TODO(ganshun): compute an index for the ioapic array. */
	int ix = 0;
	uint32_t offset = gpa & 0xfffff;
	/* basic sanity tests. */
	DPRINTF("%s: %p 0x%x %p %s\n", __func__, (void *)gpa, destreg, regp,
		store ? "write" : "read");

	if ((offset != 0) && (offset != 0x10)) {
		DPRINTF("Bad register offset: 0x%x and has to be 0x0 or 0x10\n",
			offset);
		return -1;
	}

	if (store) {
		ioapic_write(vm_thread, ix, offset, *regp);
	} else {
		*regp = ioapic_read(vm_thread, ix, offset);
	}
	return 0;
}
