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

#include <stdio.h>
#include <sys/types.h>
#include <pthread.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 = 1;
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;
		break;
	case 1:
		return 0x170011;
		break;
	case 2:
		return ioapic[ix].arbid;
		break;
	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;
		break;
	}
	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);
		}
	}

	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);
	}

}
