/* Copyright (c) 2017 Google Inc.
 * See LICENSE for details.
 *
 * ACPI setup. */

#include <stdio.h>
#include <stdlib.h>
#include <sys/fcntl.h>
#include <sys/mman.h>
#include <ros/arch/mmu.h>
#include <vmm/util.h>
#include <vmm/vmm.h>

#include <vmm/acpi/acpi.h>
#include <vmm/acpi/vmm_simple_dsdt.h>

/* By 1999, you could just scan the hardware
 * and work it out. But 2005, that was no longer possible. How sad.
 * so we have to fake acpi to make it all work.
 * This will be copied to memory at 0xe0000, so the kernel can find it.
 */

/* assume they're all 256 bytes long just to make it easy.
 * Just have pointers that point to aligned things.
 */

struct acpi_table_rsdp rsdp = {
	.signature = ACPI_SIG_RSDP,
	.oem_id = "AKAROS",
	.revision = 2,
	.length = 36,
};

struct acpi_table_xsdt xsdt = {
	.header = {
		.signature = ACPI_SIG_DSDT,
		.revision = 2,
		.oem_id = "AKAROS",
		.oem_table_id = "ALPHABET",
		.oem_revision = 0,
		.asl_compiler_id = "RON ",
		.asl_compiler_revision = 0,
	},
};
struct acpi_table_fadt fadt = {
	.header = {
		.signature = ACPI_SIG_FADT,
		.revision = 2,
		.oem_id = "AKAROS",
		.oem_table_id = "ALPHABET",
		.oem_revision = 0,
		.asl_compiler_id = "RON ",
		.asl_compiler_revision = 0,
	},
};


/* This has to be dropped into memory, then the other crap just follows it.
 */
struct acpi_table_madt madt = {
	.header = {
		.signature = ACPI_SIG_MADT,
		.revision = 2,
		.oem_id = "AKAROS",
		.oem_table_id = "ALPHABET",
		.oem_revision = 0,
		.asl_compiler_id = "RON ",
		.asl_compiler_revision = 0,
	},

	.address = APIC_GPA,
	.flags = 0,
};

struct acpi_madt_io_apic
	Apic1 = {.header = {.type = ACPI_MADT_TYPE_IO_APIC,
	         .length = sizeof(struct acpi_madt_io_apic)},
	         .id = 0, .address = 0xfec00000, .global_irq_base = 0};

struct acpi_madt_interrupt_override isor[] = {
	/* From the ACPI Specification Version 6.1: For example, if your machine
	 * has the ISA Programmable Interrupt Timer (PIT) connected to ISA IRQ
	 * 0, but in APIC mode, it is connected to I/O APIC interrupt input 2,
	 * then you would need an Interrupt Source Override where the source
	 * entry is ‘0’ and the Global System Interrupt is ‘2.’ */
};

void lowmem(void)
{
	asm volatile (".section .lowmem, \"aw\";"
	              "low: ;"
	              ".=0x1000;"
	              ".align 0x100000;"
	              ".previous;");
}

static uint8_t acpi_tb_checksum(uint8_t *buffer, uint32_t length)
{
	uint8_t sum = 0;
	uint8_t *end = buffer + length;

	fprintf(stderr, "tbchecksum %p for %d", buffer, length);
	while (buffer < end) {
		if (end - buffer < 2)
			fprintf(stderr, "%02x\n", sum);
		sum = (uint8_t)(sum + *(buffer++));
	}
	fprintf(stderr, " is %02x\n", sum);
	return sum;
}

static void gencsum(uint8_t *target, void *data, int len)
{
	uint8_t csum;

	// blast target to zero so it does not get counted
	// (it might be in the struct we checksum) And, yes, it is, goodness.
	fprintf(stderr, "gencsum %p target %p source %d bytes\n", target, data,
	        len);
	*target = 0;
	csum = acpi_tb_checksum((uint8_t *)data, len);
	*target = ~csum + 1;
	fprintf(stderr, "Cmoputed is %02x\n", *target);
}

/* Initialize the MADT structs for each local apic. */
static void *init_madt_local_apic(struct virtual_machine *vm, void *start)
{
	struct acpi_madt_local_apic *apic = start;

	for (int i = 0; i < vm->nr_gpcs; i++) {
		apic->header.type = ACPI_MADT_TYPE_LOCAL_APIC;
		apic->header.length = sizeof(struct acpi_madt_local_apic);
		apic->processor_id = i;
		apic->id = i;
		apic->lapic_flags = 1;
		apic = (void *)apic + sizeof(struct acpi_madt_local_apic);
	}
	return apic;
}

/* Initialize the MADT structs for each local x2apic. */
static void *init_madt_local_x2apic(struct virtual_machine *vm, void *start)
{
	struct acpi_madt_local_x2apic *apic = start;

	for (int i = 0; i < vm->nr_gpcs; i++) {
		apic->header.type = ACPI_MADT_TYPE_LOCAL_X2APIC;
		apic->header.length = sizeof(struct acpi_madt_local_x2apic);
		apic->local_apic_id = i;
		apic->uid = i;
		apic->lapic_flags = 1;
		apic = (void *)apic + sizeof(struct acpi_madt_local_x2apic);
	}
	return apic;
}

/* smbios reads the smbios into the e segment. By convention the
 * e segment includes the f segment and is 128 kbytes. */
static int smbios(char *smbiostable, void *esegment)
{
	int amt;

	amt = cat(smbiostable, esegment, 128 * 1024);
	if (amt < 0) {
		fprintf(stderr, "%s: %r\n", smbiostable);
		exit(1);
	}

	return amt;
}

void *setup_biostables(struct virtual_machine *vm,
                       void *a, void *smbiostable)
{
	struct acpi_table_rsdp *r;
	struct acpi_table_fadt *f;
	struct acpi_table_madt *m;
	struct acpi_table_xsdt *x;
	void *low1m;
	uint8_t csum;


	// The low 1m is so we can fill in bullshit like ACPI.
	// And, sorry, due to the STUPID format of the RSDP for now we need the
	// low 1M.
	low1m = mmap((int*)4096, MiB-4096, PROT_READ | PROT_WRITE,
	             MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
	if (low1m != (void *)4096) {
		perror("Unable to mmap low 1m");
		exit(1);
	}

	/* As I understood it, the spec was that SMBIOS
	 * tables live at f0000. We've been finding that
	 * they can have pointers to exxxx. So, for now,
	 * we assume you will take a 128K snapshot of flash
	 * and we'll just splat the whole mess in at
	 * 0xe0000. We can get more sophisticated about
	 * this later if needed. TODO: parse the table,
	 * and make sure that ACPI doesn't trash it.
	 * Although you'll know instantly if that happens
	 * as you'll get dmidecode errors. But it still needs
	 * to be better. */
	if (smbiostable) {
		fprintf(stderr, "Using SMBIOS table %s\n", smbiostable);
		smbios(smbiostable, (void *)0xe0000);
	}

	r = a;
	fprintf(stderr, "install rsdp to %p\n", r);
	*r = rsdp;
	a += sizeof(*r);
	r->xsdt_physical_address = (uint64_t)a;
	gencsum(&r->checksum, r, ACPI_RSDP_CHECKSUM_LENGTH);
	csum = acpi_tb_checksum((uint8_t *) r, ACPI_RSDP_CHECKSUM_LENGTH);
	if (csum != 0) {
		fprintf(stderr, "RSDP has bad checksum; summed to %x\n", csum);
		exit(1);
	}

	/* Check extended checksum if table version >= 2 */
	gencsum(&r->extended_checksum, r, ACPI_RSDP_XCHECKSUM_LENGTH);
	if ((rsdp.revision >= 2) &&
	    (acpi_tb_checksum((uint8_t*)r, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) {
		fprintf(stderr, "RSDP has bad checksum v2\n");
		exit(1);
	}

	/* just leave a bunch of space for the xsdt. */
	/* we need to zero the area since it has pointers. */
	x = a;
	a += sizeof(*x) + 8*sizeof(void *);
	memset(x, 0, a - (void *)x);
	fprintf(stderr, "install xsdt to %p\n", x);
	*x = xsdt;
	x->table_offset_entry[0] = 0;
	x->table_offset_entry[1] = 0;
	x->header.length = a - (void *)x;

	f = a;
	fprintf(stderr, "install fadt to %p\n", f);
	*f = fadt;
	x->table_offset_entry[0] = (uint64_t)f; // fadt MUST be first in xsdt!
	a += sizeof(*f);
	f->header.length = a - (void *)f;

	f->Xdsdt = (uint64_t) a;
	fprintf(stderr, "install dsdt to %p\n", a);
	memcpy(a, &DSDT_DSDTTBL_Header, 36);
	a += 36;

	gencsum(&f->header.checksum, f, f->header.length);
	if (acpi_tb_checksum((uint8_t *)f, f->header.length) != 0) {
		fprintf(stderr, "fadt has bad checksum v2\n");
		exit(1);
	}

	m = a;
	*m = madt;
	x->table_offset_entry[3] = (uint64_t) m;
	a += sizeof(*m);
	fprintf(stderr, "install madt to %p\n", m);

	a = init_madt_local_apic(vm, a);

	memmove(a, &Apic1, sizeof(Apic1));
	a += sizeof(Apic1);

	a = init_madt_local_x2apic(vm, a);

	memmove(a, &isor, sizeof(isor));
	a += sizeof(isor);
	m->header.length = a - (void *)m;

	gencsum(&m->header.checksum, m, m->header.length);
	if (acpi_tb_checksum((uint8_t *) m, m->header.length) != 0) {
		fprintf(stderr, "madt has bad checksum v2\n");
		exit(1);
	}

	gencsum(&x->header.checksum, x, x->header.length);
	csum = acpi_tb_checksum((uint8_t *) x, x->header.length);
	if (csum != 0) {
		fprintf(stderr, "XSDT has bad checksum; summed to %x\n", csum);
		exit(1);
	}

	fprintf(stderr, "allchecksums ok\n");

	a = (void *)(((unsigned long)a + 0xfff) & ~0xfff);

	return a;
}
