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

#include <parlib/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;

	while (buffer < end)
		sum = (uint8_t)(sum + *(buffer++));
	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.
	*target = 0;
	csum = acpi_tb_checksum((uint8_t *)data, len);
	*target = ~csum + 1;
}

/* 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;
	*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);
	*x = xsdt;
	x->table_offset_entry[0] = 0;
	x->table_offset_entry[1] = 0;
	x->header.length = a - (void *)x;

	f = a;
	*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;
	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);

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

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

	return a;
}
