/*
 *  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_rev2 *fadt =
		    (struct fadt_descriptor_rev2 *)*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 *)__va(rsdp_phys);
	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;
}
