/*
 *  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		256

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];

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