/*
 *  acpi_tables.c - ACPI Boot-Time Table Parsing
 *
 *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 */

#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/irq.h>
#include <linux/errno.h>
#include <linux/acpi.h>
#include <linux/bootmem.h>

#define PREFIX			"ACPI: "

#define ACPI_MAX_TABLES		128

static char *acpi_table_signatures[ACPI_TABLE_COUNT] = {
	[ACPI_TABLE_UNKNOWN] = "????",
	[ACPI_APIC] = "APIC",
	[ACPI_BOOT] = "BOOT",
	[ACPI_DBGP] = "DBGP",
	[ACPI_DSDT] = "DSDT",
	[ACPI_ECDT] = "ECDT",
	[ACPI_ETDT] = "ETDT",
	[ACPI_FADT] = "FACP",
	[ACPI_FACS] = "FACS",
	[ACPI_OEMX] = "OEM",
	[ACPI_PSDT] = "PSDT",
	[ACPI_SBST] = "SBST",
	[ACPI_SLIT] = "SLIT",
	[ACPI_SPCR] = "SPCR",
	[ACPI_SRAT] = "SRAT",
	[ACPI_SSDT] = "SSDT",
	[ACPI_SPMI] = "SPMI",
	[ACPI_HPET] = "HPET",
	[ACPI_MCFG] = "MCFG",
};

static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" };
static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" };

/* System Description Table (RSDT/XSDT) */
struct acpi_table_sdt {
	unsigned long pa;
	enum acpi_table_id id;
	unsigned long size;
} __attribute__ ((packed));

static unsigned long sdt_pa;	/* Physical Address */
static unsigned long sdt_count;	/* Table count */

static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES] __initdata;

void acpi_table_print(struct acpi_table_header *header, unsigned long phys_addr)
{
	char *name = NULL;

	if (!header)
		return;

	/* Some table signatures aren't good table names */

	if (!strncmp((char *)&header->signature,
		     acpi_table_signatures[ACPI_APIC],
		     sizeof(header->signature))) {
		name = "MADT";
	} else if (!strncmp((char *)&header->signature,
			    acpi_table_signatures[ACPI_FADT],
			    sizeof(header->signature))) {
		name = "FADT";
	} else
		name = header->signature;

	printk(KERN_DEBUG PREFIX
	       "%.4s (v%3.3d %6.6s %8.8s 0x%08x %.4s 0x%08x) @ 0x%p\n", name,
	       header->revision, header->oem_id, header->oem_table_id,
	       header->oem_revision, header->asl_compiler_id,
	       header->asl_compiler_revision, (void *)phys_addr);
}

void acpi_table_print_madt_entry(acpi_table_entry_header * header)
{
	if (!header)
		return;

	switch (header->type) {

	case ACPI_MADT_LAPIC:
		{
			struct acpi_table_lapic *p =
			    (struct acpi_table_lapic *)header;
			printk(KERN_INFO PREFIX
			       "LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n",
			       p->acpi_id, p->id,
			       p->flags.enabled ? "enabled" : "disabled");
		}
		break;

	case ACPI_MADT_IOAPIC:
		{
			struct acpi_table_ioapic *p =
			    (struct acpi_table_ioapic *)header;
			printk(KERN_INFO PREFIX
			       "IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n",
			       p->id, p->address, p->global_irq_base);
		}
		break;

	case ACPI_MADT_INT_SRC_OVR:
		{
			struct acpi_table_int_src_ovr *p =
			    (struct acpi_table_int_src_ovr *)header;
			printk(KERN_INFO PREFIX
			       "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n",
			       p->bus, p->bus_irq, p->global_irq,
			       mps_inti_flags_polarity[p->flags.polarity],
			       mps_inti_flags_trigger[p->flags.trigger]);
			if (p->flags.reserved)
				printk(KERN_INFO PREFIX
				       "INT_SRC_OVR unexpected reserved flags: 0x%x\n",
				       p->flags.reserved);

		}
		break;

	case ACPI_MADT_NMI_SRC:
		{
			struct acpi_table_nmi_src *p =
			    (struct acpi_table_nmi_src *)header;
			printk(KERN_INFO PREFIX
			       "NMI_SRC (%s %s global_irq %d)\n",
			       mps_inti_flags_polarity[p->flags.polarity],
			       mps_inti_flags_trigger[p->flags.trigger],
			       p->global_irq);
		}
		break;

	case ACPI_MADT_LAPIC_NMI:
		{
			struct acpi_table_lapic_nmi *p =
			    (struct acpi_table_lapic_nmi *)header;
			printk(KERN_INFO PREFIX
			       "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n",
			       p->acpi_id,
			       mps_inti_flags_polarity[p->flags.polarity],
			       mps_inti_flags_trigger[p->flags.trigger],
			       p->lint);
		}
		break;

	case ACPI_MADT_LAPIC_ADDR_OVR:
		{
			struct acpi_table_lapic_addr_ovr *p =
			    (struct acpi_table_lapic_addr_ovr *)header;
			printk(KERN_INFO PREFIX
			       "LAPIC_ADDR_OVR (address[%p])\n",
			       (void *)(unsigned long)p->address);
		}
		break;

	case ACPI_MADT_IOSAPIC:
		{
			struct acpi_table_iosapic *p =
			    (struct acpi_table_iosapic *)header;
			printk(KERN_INFO PREFIX
			       "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n",
			       p->id, (void *)(unsigned long)p->address,
			       p->global_irq_base);
		}
		break;

	case ACPI_MADT_LSAPIC:
		{
			struct acpi_table_lsapic *p =
			    (struct acpi_table_lsapic *)header;
			printk(KERN_INFO PREFIX
			       "LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n",
			       p->acpi_id, p->id, p->eid,
			       p->flags.enabled ? "enabled" : "disabled");
		}
		break;

	case ACPI_MADT_PLAT_INT_SRC:
		{
			struct acpi_table_plat_int_src *p =
			    (struct acpi_table_plat_int_src *)header;
			printk(KERN_INFO PREFIX
			       "PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n",
			       mps_inti_flags_polarity[p->flags.polarity],
			       mps_inti_flags_trigger[p->flags.trigger],
			       p->type, p->id, p->eid, p->iosapic_vector,
			       p->global_irq);
		}
		break;

	default:
		printk(KERN_WARNING PREFIX
		       "Found unsupported MADT entry (type = 0x%x)\n",
		       header->type);
		break;
	}
}

static int
acpi_table_compute_checksum(void *table_pointer, unsigned long length)
{
	u8 *p = (u8 *) table_pointer;
	unsigned long remains = length;
	unsigned long sum = 0;

	if (!p || !length)
		return -EINVAL;

	while (remains--)
		sum += *p++;

	return (sum & 0xFF);
}

/*
 * acpi_get_table_header_early()
 * for acpi_blacklisted(), acpi_table_get_sdt()
 */
int __init
acpi_get_table_header_early(enum acpi_table_id id,
			    struct acpi_table_header **header)
{
	unsigned int i;
	enum acpi_table_id temp_id;

	/* DSDT is different from the rest */
	if (id == ACPI_DSDT)
		temp_id = ACPI_FADT;
	else
		temp_id = id;

	/* Locate the table. */

	for (i = 0; i < sdt_count; i++) {
		if (sdt_entry[i].id != temp_id)
			continue;
		*header = (void *)
		    __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
		if (!*header) {
			printk(KERN_WARNING PREFIX "Unable to map %s\n",
			       acpi_table_signatures[temp_id]);
			return -ENODEV;
		}
		break;
	}

	if (!*header) {
		printk(KERN_WARNING PREFIX "%s not present\n",
		       acpi_table_signatures[id]);
		return -ENODEV;
	}

	/* Map the DSDT header via the pointer in the FADT */
	if (id == ACPI_DSDT) {
		struct fadt_descriptor *fadt =
		    (struct fadt_descriptor *)*header;

		if (fadt->revision == 3 && fadt->Xdsdt) {
			*header = (void *)__acpi_map_table(fadt->Xdsdt,
							   sizeof(struct
								  acpi_table_header));
		} else if (fadt->V1_dsdt) {
			*header = (void *)__acpi_map_table(fadt->V1_dsdt,
							   sizeof(struct
								  acpi_table_header));
		} else
			*header = NULL;

		if (!*header) {
			printk(KERN_WARNING PREFIX "Unable to map DSDT\n");
			return -ENODEV;
		}
	}

	return 0;
}

int __init
acpi_table_parse_madt_family(enum acpi_table_id id,
			     unsigned long madt_size,
			     int entry_id,
			     acpi_madt_entry_handler handler,
			     unsigned int max_entries)
{
	void *madt = NULL;
	acpi_table_entry_header *entry;
	unsigned int count = 0;
	unsigned long madt_end;
	unsigned int i;

	if (!handler)
		return -EINVAL;

	/* Locate the MADT (if exists). There should only be one. */

	for (i = 0; i < sdt_count; i++) {
		if (sdt_entry[i].id != id)
			continue;
		madt = (void *)
		    __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
		if (!madt) {
			printk(KERN_WARNING PREFIX "Unable to map %s\n",
			       acpi_table_signatures[id]);
			return -ENODEV;
		}
		break;
	}

	if (!madt) {
		printk(KERN_WARNING PREFIX "%s not present\n",
		       acpi_table_signatures[id]);
		return -ENODEV;
	}

	madt_end = (unsigned long)madt + sdt_entry[i].size;

	/* Parse all entries looking for a match. */

	entry = (acpi_table_entry_header *)
	    ((unsigned long)madt + madt_size);

	while (((unsigned long)entry) + sizeof(acpi_table_entry_header) <
	       madt_end) {
		if (entry->type == entry_id
		    && (!max_entries || count++ < max_entries))
			if (handler(entry, madt_end))
				return -EINVAL;

		entry = (acpi_table_entry_header *)
		    ((unsigned long)entry + entry->length);
	}
	if (max_entries && count > max_entries) {
		printk(KERN_WARNING PREFIX "[%s:0x%02x] ignored %i entries of "
		       "%i found\n", acpi_table_signatures[id], entry_id,
		       count - max_entries, count);
	}

	return count;
}

int __init
acpi_table_parse_madt(enum acpi_madt_entry_id id,
		      acpi_madt_entry_handler handler, unsigned int max_entries)
{
	return acpi_table_parse_madt_family(ACPI_APIC,
					    sizeof(struct acpi_table_madt), id,
					    handler, max_entries);
}

int __init acpi_table_parse(enum acpi_table_id id, acpi_table_handler handler)
{
	int count = 0;
	unsigned int i = 0;

	if (!handler)
		return -EINVAL;

	for (i = 0; i < sdt_count; i++) {
		if (sdt_entry[i].id != id)
			continue;
		count++;
		if (count == 1)
			handler(sdt_entry[i].pa, sdt_entry[i].size);

		else
			printk(KERN_WARNING PREFIX
			       "%d duplicate %s table ignored.\n", count,
			       acpi_table_signatures[id]);
	}

	return count;
}

static int __init acpi_table_get_sdt(struct acpi_table_rsdp *rsdp)
{
	struct acpi_table_header *header = NULL;
	unsigned int i, id = 0;

	if (!rsdp)
		return -EINVAL;

	/* First check XSDT (but only on ACPI 2.0-compatible systems) */

	if ((rsdp->revision >= 2) &&
	    (((struct acpi20_table_rsdp *)rsdp)->xsdt_address)) {

		struct acpi_table_xsdt *mapped_xsdt = NULL;

		sdt_pa = ((struct acpi20_table_rsdp *)rsdp)->xsdt_address;

		/* map in just the header */
		header = (struct acpi_table_header *)
		    __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));

		if (!header) {
			printk(KERN_WARNING PREFIX
			       "Unable to map XSDT header\n");
			return -ENODEV;
		}

		/* remap in the entire table before processing */
		mapped_xsdt = (struct acpi_table_xsdt *)
		    __acpi_map_table(sdt_pa, header->length);
		if (!mapped_xsdt) {
			printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
			return -ENODEV;
		}
		header = &mapped_xsdt->header;

		if (strncmp(header->signature, "XSDT", 4)) {
			printk(KERN_WARNING PREFIX
			       "XSDT signature incorrect\n");
			return -ENODEV;
		}

		if (acpi_table_compute_checksum(header, header->length)) {
			printk(KERN_WARNING PREFIX "Invalid XSDT checksum\n");
			return -ENODEV;
		}

		sdt_count =
		    (header->length - sizeof(struct acpi_table_header)) >> 3;
		if (sdt_count > ACPI_MAX_TABLES) {
			printk(KERN_WARNING PREFIX
			       "Truncated %lu XSDT entries\n",
			       (sdt_count - ACPI_MAX_TABLES));
			sdt_count = ACPI_MAX_TABLES;
		}

		for (i = 0; i < sdt_count; i++)
			sdt_entry[i].pa = (unsigned long)mapped_xsdt->entry[i];
	}

	/* Then check RSDT */

	else if (rsdp->rsdt_address) {

		struct acpi_table_rsdt *mapped_rsdt = NULL;

		sdt_pa = rsdp->rsdt_address;

		/* map in just the header */
		header = (struct acpi_table_header *)
		    __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
		if (!header) {
			printk(KERN_WARNING PREFIX
			       "Unable to map RSDT header\n");
			return -ENODEV;
		}

		/* remap in the entire table before processing */
		mapped_rsdt = (struct acpi_table_rsdt *)
		    __acpi_map_table(sdt_pa, header->length);
		if (!mapped_rsdt) {
			printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
			return -ENODEV;
		}
		header = &mapped_rsdt->header;

		if (strncmp(header->signature, "RSDT", 4)) {
			printk(KERN_WARNING PREFIX
			       "RSDT signature incorrect\n");
			return -ENODEV;
		}

		if (acpi_table_compute_checksum(header, header->length)) {
			printk(KERN_WARNING PREFIX "Invalid RSDT checksum\n");
			return -ENODEV;
		}

		sdt_count =
		    (header->length - sizeof(struct acpi_table_header)) >> 2;
		if (sdt_count > ACPI_MAX_TABLES) {
			printk(KERN_WARNING PREFIX
			       "Truncated %lu RSDT entries\n",
			       (sdt_count - ACPI_MAX_TABLES));
			sdt_count = ACPI_MAX_TABLES;
		}

		for (i = 0; i < sdt_count; i++)
			sdt_entry[i].pa = (unsigned long)mapped_rsdt->entry[i];
	}

	else {
		printk(KERN_WARNING PREFIX
		       "No System Description Table (RSDT/XSDT) specified in RSDP\n");
		return -ENODEV;
	}

	acpi_table_print(header, sdt_pa);

	for (i = 0; i < sdt_count; i++) {

		/* map in just the header */
		header = (struct acpi_table_header *)
		    __acpi_map_table(sdt_entry[i].pa,
				     sizeof(struct acpi_table_header));
		if (!header)
			continue;

		/* remap in the entire table before processing */
		header = (struct acpi_table_header *)
		    __acpi_map_table(sdt_entry[i].pa, header->length);
		if (!header)
			continue;

		acpi_table_print(header, sdt_entry[i].pa);

		if (acpi_table_compute_checksum(header, header->length)) {
			printk(KERN_WARNING "  >>> ERROR: Invalid checksum\n");
			continue;
		}

		sdt_entry[i].size = header->length;

		for (id = 0; id < ACPI_TABLE_COUNT; id++) {
			if (!strncmp((char *)&header->signature,
				     acpi_table_signatures[id],
				     sizeof(header->signature))) {
				sdt_entry[i].id = id;
			}
		}
	}

	/* 
	 * The DSDT is *not* in the RSDT (why not? no idea.) but we want
	 * to print its info, because this is what people usually blacklist
	 * against. Unfortunately, we don't know the phys_addr, so just
	 * print 0. Maybe no one will notice.
	 */
	if (!acpi_get_table_header_early(ACPI_DSDT, &header))
		acpi_table_print(header, 0);

	return 0;
}

/*
 * acpi_table_init()
 *
 * find RSDP, find and checksum SDT/XSDT.
 * checksum all tables, print SDT/XSDT
 * 
 * result: sdt_entry[] is initialized
 */

int __init acpi_table_init(void)
{
	struct acpi_table_rsdp *rsdp = NULL;
	unsigned long rsdp_phys = 0;
	int result = 0;

	/* Locate and map the Root System Description Table (RSDP) */

	rsdp_phys = acpi_find_rsdp();
	if (!rsdp_phys) {
		printk(KERN_ERR PREFIX "Unable to locate RSDP\n");
		return -ENODEV;
	}

	rsdp = (struct acpi_table_rsdp *)__acpi_map_table(rsdp_phys,
		sizeof(struct acpi_table_rsdp));
	if (!rsdp) {
		printk(KERN_WARNING PREFIX "Unable to map RSDP\n");
		return -ENODEV;
	}

	printk(KERN_DEBUG PREFIX
	       "RSDP (v%3.3d %6.6s                                ) @ 0x%p\n",
	       rsdp->revision, rsdp->oem_id, (void *)rsdp_phys);

	if (rsdp->revision < 2)
		result =
		    acpi_table_compute_checksum(rsdp,
						sizeof(struct acpi_table_rsdp));
	else
		result =
		    acpi_table_compute_checksum(rsdp,
						((struct acpi20_table_rsdp *)
						 rsdp)->length);

	if (result) {
		printk(KERN_WARNING "  >>> ERROR: Invalid checksum\n");
		return -ENODEV;
	}

	/* Locate and map the System Description table (RSDT/XSDT) */

	if (acpi_table_get_sdt(rsdp))
		return -ENODEV;

	return 0;
}
