/*
 *  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/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 = 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;
}
