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

#include <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;
}
