/* sfi_core.c Simple Firmware Interface - core internals */

/*

  This file is provided under a dual BSD/GPLv2 license.  When using or
  redistributing this file, you may do so under either license.

  GPL LICENSE SUMMARY

  Copyright(c) 2009 Intel Corporation. All rights reserved.

  This program is free software; you can redistribute it and/or modify
  it under the terms of version 2 of the GNU General Public License as
  published by the Free Software Foundation.

  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., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  The full GNU General Public License is included in this distribution
  in the file called LICENSE.GPL.

  BSD LICENSE

  Copyright(c) 2009 Intel Corporation. All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the
      distribution.
    * Neither the name of Intel Corporation nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#define KMSG_COMPONENT "SFI"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

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

#include <asm/pgtable.h>

#include "sfi_core.h"

#define ON_SAME_PAGE(addr1, addr2) \
	(((unsigned long)(addr1) & PAGE_MASK) == \
	((unsigned long)(addr2) & PAGE_MASK))
#define TABLE_ON_PAGE(page, table, size) (ON_SAME_PAGE(page, table) && \
				ON_SAME_PAGE(page, table + size))

int sfi_disabled __read_mostly;
EXPORT_SYMBOL(sfi_disabled);

static u64 syst_pa __read_mostly;
static struct sfi_table_simple *syst_va __read_mostly;

/*
 * FW creates and saves the SFI tables in memory. When these tables get
 * used, they may need to be mapped to virtual address space, and the mapping
 * can happen before or after the ioremap() is ready, so a flag is needed
 * to indicating this
 */
static u32 sfi_use_ioremap __read_mostly;

static void __iomem *sfi_map_memory(u64 phys, u32 size)
{
	if (!phys || !size)
		return NULL;

	if (sfi_use_ioremap)
		return ioremap(phys, size);
	else
		return early_ioremap(phys, size);
}

static void sfi_unmap_memory(void __iomem *virt, u32 size)
{
	if (!virt || !size)
		return;

	if (sfi_use_ioremap)
		iounmap(virt);
	else
		early_iounmap(virt, size);
}

static void sfi_print_table_header(unsigned long long pa,
				struct sfi_table_header *header)
{
	pr_info("%4.4s %llX, %04X (v%d %6.6s %8.8s)\n",
		header->sig, pa,
		header->len, header->rev, header->oem_id,
		header->oem_table_id);
}

/*
 * sfi_verify_table()
 * Sanity check table lengh, calculate checksum
 */
static __init int sfi_verify_table(struct sfi_table_header *table)
{

	u8 checksum = 0;
	u8 *puchar = (u8 *)table;
	u32 length = table->len;

	/* Sanity check table length against arbitrary 1MB limit */
	if (length > 0x100000) {
		pr_err("Invalid table length 0x%x\n", length);
		return -1;
	}

	while (length--)
		checksum += *puchar++;

	if (checksum) {
		pr_err("Checksum %2.2X should be %2.2X\n",
			table->csum, table->csum - checksum);
		return -1;
	}
	return 0;
}

/*
 * sfi_map_table()
 *
 * Return address of mapped table
 * Check for common case that we can re-use mapping to SYST,
 * which requires syst_pa, syst_va to be initialized.
 */
struct sfi_table_header *sfi_map_table(u64 pa)
{
	struct sfi_table_header *th;
	u32 length;

	if (!TABLE_ON_PAGE(syst_pa, pa, sizeof(struct sfi_table_header)))
		th = sfi_map_memory(pa, sizeof(struct sfi_table_header));
	else
		th = (void *)syst_va + (pa - syst_pa);

	 /* If table fits on same page as its header, we are done */
	if (TABLE_ON_PAGE(th, th, th->len))
		return th;

	/* Entire table does not fit on same page as SYST */
	length = th->len;
	if (!TABLE_ON_PAGE(syst_pa, pa, sizeof(struct sfi_table_header)))
		sfi_unmap_memory(th, sizeof(struct sfi_table_header));

	return sfi_map_memory(pa, length);
}

/*
 * sfi_unmap_table()
 *
 * Undoes effect of sfi_map_table() by unmapping table
 * if it did not completely fit on same page as SYST.
 */
void sfi_unmap_table(struct sfi_table_header *th)
{
	if (!TABLE_ON_PAGE(syst_va, th, th->len))
		sfi_unmap_memory(th, TABLE_ON_PAGE(th, th, th->len) ?
					sizeof(*th) : th->len);
}

static int sfi_table_check_key(struct sfi_table_header *th,
				struct sfi_table_key *key)
{

	if (strncmp(th->sig, key->sig, SFI_SIGNATURE_SIZE)
		|| (key->oem_id && strncmp(th->oem_id,
				key->oem_id, SFI_OEM_ID_SIZE))
		|| (key->oem_table_id && strncmp(th->oem_table_id,
				key->oem_table_id, SFI_OEM_TABLE_ID_SIZE)))
		return -1;

	return 0;
}

/*
 * This function will be used in 2 cases:
 * 1. used to enumerate and verify the tables addressed by SYST/XSDT,
 *    thus no signature will be given (in kernel boot phase)
 * 2. used to parse one specific table, signature must exist, and
 *    the mapped virt address will be returned, and the virt space
 *    will be released by call sfi_put_table() later
 *
 * Return value:
 *	NULL:			when can't find a table matching the key
 *	ERR_PTR(error):		error value
 *	virt table address:	when a matched table is found
 */
struct sfi_table_header *sfi_check_table(u64 pa, struct sfi_table_key *key)
{
	struct sfi_table_header *th;
	void *ret = NULL;

	th = sfi_map_table(pa);
	if (!th)
		return ERR_PTR(-ENOMEM);

	if (!key->sig) {
		sfi_print_table_header(pa, th);
		if (sfi_verify_table(th))
			ret = ERR_PTR(-EINVAL);
	} else {
		if (!sfi_table_check_key(th, key))
			return th;	/* Success */
	}

	sfi_unmap_table(th);
	return ret;
}

/*
 * sfi_get_table()
 *
 * Search SYST for the specified table with the signature in
 * the key, and return the mapped table
 */
struct sfi_table_header *sfi_get_table(struct sfi_table_key *key)
{
	struct sfi_table_header *th;
	u32 tbl_cnt, i;

	tbl_cnt = SFI_GET_NUM_ENTRIES(syst_va, u64);
	for (i = 0; i < tbl_cnt; i++) {
		th = sfi_check_table(syst_va->pentry[i], key);
		if (!IS_ERR(th) && th)
			return th;
	}

	return NULL;
}

void sfi_put_table(struct sfi_table_header *th)
{
	sfi_unmap_table(th);
}

/* Find table with signature, run handler on it */
int sfi_table_parse(char *signature, char *oem_id, char *oem_table_id,
			sfi_table_handler handler)
{
	struct sfi_table_header *table = NULL;
	struct sfi_table_key key;
	int ret = -EINVAL;

	if (sfi_disabled || !handler || !signature)
		goto exit;

	key.sig = signature;
	key.oem_id = oem_id;
	key.oem_table_id = oem_table_id;

	table = sfi_get_table(&key);
	if (!table)
		goto exit;

	ret = handler(table);
	sfi_put_table(table);
exit:
	return ret;
}
EXPORT_SYMBOL_GPL(sfi_table_parse);

/*
 * sfi_parse_syst()
 * Checksum all the tables in SYST and print their headers
 *
 * success: set syst_va, return 0
 */
static int __init sfi_parse_syst(void)
{
	struct sfi_table_key key = SFI_ANY_KEY;
	int tbl_cnt, i;
	void *ret;

	syst_va = sfi_map_memory(syst_pa, sizeof(struct sfi_table_simple));
	if (!syst_va)
		return -ENOMEM;

	tbl_cnt = SFI_GET_NUM_ENTRIES(syst_va, u64);
	for (i = 0; i < tbl_cnt; i++) {
		ret = sfi_check_table(syst_va->pentry[i], &key);
		if (IS_ERR(ret))
			return PTR_ERR(ret);
	}

	return 0;
}

/*
 * The OS finds the System Table by searching 16-byte boundaries between
 * physical address 0x000E0000 and 0x000FFFFF. The OS shall search this region
 * starting at the low address and shall stop searching when the 1st valid SFI
 * System Table is found.
 *
 * success: set syst_pa, return 0
 * fail: return -1
 */
static __init int sfi_find_syst(void)
{
	unsigned long offset, len;
	void *start;

	len = SFI_SYST_SEARCH_END - SFI_SYST_SEARCH_BEGIN;
	start = sfi_map_memory(SFI_SYST_SEARCH_BEGIN, len);
	if (!start)
		return -1;

	for (offset = 0; offset < len; offset += 16) {
		struct sfi_table_header *syst_hdr;

		syst_hdr = start + offset;
		if (strncmp(syst_hdr->sig, SFI_SIG_SYST,
				SFI_SIGNATURE_SIZE))
			continue;

		if (syst_hdr->len > PAGE_SIZE)
			continue;

		sfi_print_table_header(SFI_SYST_SEARCH_BEGIN + offset,
					syst_hdr);

		if (sfi_verify_table(syst_hdr))
			continue;

		/*
		 * Enforce SFI spec mandate that SYST reside within a page.
		 */
		if (!ON_SAME_PAGE(syst_pa, syst_pa + syst_hdr->len)) {
			pr_info("SYST 0x%llx + 0x%x crosses page\n",
					syst_pa, syst_hdr->len);
			continue;
		}

		/* Success */
		syst_pa = SFI_SYST_SEARCH_BEGIN + offset;
		sfi_unmap_memory(start, len);
		return 0;
	}

	sfi_unmap_memory(start, len);
	return -1;
}

void __init sfi_init(void)
{
	if (!acpi_disabled)
		disable_sfi();

	if (sfi_disabled)
		return;

	pr_info("Simple Firmware Interface v0.7 http://simplefirmware.org\n");

	if (sfi_find_syst() || sfi_parse_syst() || sfi_platform_init())
		disable_sfi();

	return;
}

void __init sfi_init_late(void)
{
	int length;

	if (sfi_disabled)
		return;

	length = syst_va->header.len;
	sfi_unmap_memory(syst_va, sizeof(struct sfi_table_simple));

	/* Use ioremap now after it is ready */
	sfi_use_ioremap = 1;
	syst_va = sfi_map_memory(syst_pa, length);

	sfi_acpi_init();
}
