/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2013 Google Inc.
 * Copyright (C) 2015-2016 Intel Corp.
 *
 * 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; version 2 of the License.
 *
 * 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.
 */

#include <arch/hlt.h>
#include <arch/io.h>
#include <console/console.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/smm.h>
#include <device/pci_def.h>
#include <elog.h>
#include <soc/nvs.h>
#include <soc/pm.h>
#include <soc/gpio.h>
#include <soc/iomap.h>
#include <spi-generic.h>
#include <stdint.h>
#include <stdlib.h>
#include "smi.h"

/* GNVS needs to be set by coreboot initiating a software SMI. */
static struct global_nvs_t *gnvs;

__attribute__((weak)) int smm_disable_busmaster(device_t dev)
{
	return 1;
}

static void *find_save_state(const struct smm_save_state_ops *save_state_ops,
		int cmd)
{
	int node;
	void *state = NULL;
	uint32_t io_misc_info;
	uint8_t reg_al;

	/* Check all nodes looking for the one that issued the IO */
	for (node = 0; node < CONFIG_MAX_CPUS; node++) {
		state = smm_get_save_state(node);

		io_misc_info = save_state_ops->get_io_misc_info(state);

		/* Check for Synchronous IO (bit0==1) */
		if (!(io_misc_info & (1 << 0)))
			continue;
		/* Make sure it was a write (bit4==0) */
		if (io_misc_info & (1 << 4))
			continue;
		/* Check for APMC IO port */
		if (((io_misc_info >> 16) & 0xff) != APM_CNT)
			continue;
		/* Check AL against the requested command */
		reg_al = save_state_ops->get_reg(state, RAX);
		if (reg_al != cmd)
			continue;
		break;
	}
	return state;
}

void southbridge_smi_set_eos(void)
{
	enable_smi(EOS);
}

struct global_nvs_t *smm_get_gnvs(void)
{
	return gnvs;
}

static void busmaster_disable_on_bus(int bus)
{
	int slot, func;
	unsigned int val;
	unsigned char hdr;

	for (slot = 0; slot < 0x20; slot++) {
		for (func = 0; func < 8; func++) {
			u32 reg32;
			device_t dev = PCI_DEV(bus, slot, func);

			if (!smm_disable_busmaster(dev))
				continue;
			val = pci_read_config32(dev, PCI_VENDOR_ID);

			if (val == 0xffffffff || val == 0x00000000 ||
			    val == 0x0000ffff || val == 0xffff0000)
				continue;

			/* Disable Bus Mastering for this one device */
			reg32 = pci_read_config32(dev, PCI_COMMAND);
			reg32 &= ~PCI_COMMAND_MASTER;
			pci_write_config32(dev, PCI_COMMAND, reg32);

			/* If it's not a bridge, move on. */
			hdr = pci_read_config8(dev, PCI_HEADER_TYPE);
			hdr &= 0x7f;
			if (hdr != PCI_HEADER_TYPE_BRIDGE &&
			    hdr != PCI_HEADER_TYPE_CARDBUS)
				continue;

			/*
			 * If secondary bus is equal to current bus bypass
			 * the bridge because it's likely unconfigured and
			 * would cause infinite recursion.
			 */
			int secbus = pci_read_config8(dev, PCI_SECONDARY_BUS);

			if (secbus == bus)
				continue;

			busmaster_disable_on_bus(secbus);
		}
	}
}


void southbridge_smi_sleep(const struct smm_save_state_ops *save_state_ops)
{
	uint32_t reg32;
	uint8_t slp_typ;

	/* First, disable further SMIs */
	disable_smi(SLP_SMI_EN);
	/* Figure out SLP_TYP */
	reg32 = inl(ACPI_PMIO_BASE + PM1_CNT);
	printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);
	slp_typ = acpi_sleep_from_pm1(reg32);

	/* Do any mainboard sleep handling */
	mainboard_smi_sleep(slp_typ);

	/* Log S3, S4, and S5 entry */
	if (slp_typ >= ACPI_S3 && IS_ENABLED(CONFIG_ELOG_GSMI))
		elog_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ);

	/* Clear pending GPE events */
	clear_gpe_status();

	/* Next, do the deed. */

	switch (slp_typ) {
	case ACPI_S0:
		printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n");
		break;
	case ACPI_S3:
		printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");

		/* Invalidate the cache before going to S3 */
		wbinvd();
		break;
	case ACPI_S4:
		printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n");
		break;
	case ACPI_S5:
		printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");

		/* Disable all GPE */
		disable_all_gpe();
		/* also iterates over all bridges on bus 0 */
		busmaster_disable_on_bus(0);
		break;
	default:
		printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n");
		break;
	}

	/* Clear the gpio gpe0 status bits in ACPI registers */
	clear_gpi_gpe_sts();

	/* Tri-state specific GPIOS to avoid leakage during S3/S5 */

	/*
	 * Write back to the SLP register to cause the originally intended
	 * event again. We need to set BIT13 (SLP_EN) though to make the
	 * sleep happen.
	 */
	enable_pm1_control(SLP_EN);

	/* Make sure to stop executing code here for S3/S4/S5 */
	if (slp_typ >= ACPI_S3)
		hlt();

	/*
	 * In most sleep states, the code flow of this function ends at
	 * the line above. However, if we entered sleep state S1 and wake
	 * up again, we will continue to execute code in this function.
	 */
	reg32 = inl(ACPI_PMIO_BASE + PM1_CNT);
	if (reg32 & SCI_EN) {
		/* The OS is not an ACPI OS, so we set the state to S0 */
		disable_pm1_control(SLP_EN | SLP_TYP);
	}
}

static void southbridge_smi_gsmi(const struct
			smm_save_state_ops *save_state_ops)
{
	u8 sub_command, ret;
	void *io_smi = NULL;
	uint32_t reg_ebx;

	io_smi = find_save_state(save_state_ops, ELOG_GSMI_APM_CNT);
	if (!io_smi)
		return;
	/* Command and return value in EAX */
	sub_command = (save_state_ops->get_reg(io_smi, RAX) >> 8)
		& 0xff;

	/* Parameter buffer in EBX */
	reg_ebx = save_state_ops->get_reg(io_smi, RBX);

	/* drivers/elog/gsmi.c */
	ret = gsmi_exec(sub_command, &reg_ebx);
	save_state_ops->set_reg(io_smi, RAX, ret);
}

static void finalize(void)
{
	static int finalize_done;

	if (finalize_done) {
		printk(BIOS_DEBUG, "SMM already finalized.\n");
		return;
	}
	finalize_done = 1;

}

void southbridge_smi_apmc(const struct smm_save_state_ops *save_state_ops)
{
	uint8_t reg8;
	void *state = NULL;
	static int smm_initialized = 0;

	/* Emulate B2 register as the FADT / Linux expects it */

	reg8 = inb(APM_CNT);
	switch (reg8) {
	case APM_CNT_CST_CONTROL:
		/*
		 * Calling this function seems to cause
		 * some kind of race condition in Linux
		 * and causes a kernel oops
		 */
		printk(BIOS_DEBUG, "C-state control\n");
		break;
	case APM_CNT_PST_CONTROL:
		/*
		 * Calling this function seems to cause
		 * some kind of race condition in Linux
		 * and causes a kernel oops
		 */
		printk(BIOS_DEBUG, "P-state control\n");
		break;
	case APM_CNT_ACPI_DISABLE:
		disable_pm1_control(SCI_EN);
		printk(BIOS_DEBUG, "SMI#: ACPI disabled.\n");
		break;
	case APM_CNT_ACPI_ENABLE:
		enable_pm1_control(SCI_EN);
		printk(BIOS_DEBUG, "SMI#: ACPI enabled.\n");
		break;
	case APM_CNT_GNVS_UPDATE:
		if (smm_initialized) {
			printk(BIOS_DEBUG,
			       "SMI#: SMM structures already initialized!\n");
			return;
		}
		state = find_save_state(save_state_ops, reg8);
		if (state) {
			/* EBX in the state save contains the GNVS pointer */
			uint32_t reg_ebx = save_state_ops->get_reg(state, RBX);
			gnvs = (struct global_nvs_t *)(uintptr_t)reg_ebx;
			smm_initialized = 1;
			printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs);
		}
		break;
	case ELOG_GSMI_APM_CNT:
		if (IS_ENABLED(CONFIG_ELOG_GSMI))
			southbridge_smi_gsmi(save_state_ops);
		break;
	case APM_CNT_FINALIZE:
		finalize();
		break;
	}

	mainboard_smi_apmc(reg8);
}

void southbridge_smi_pm1(const struct smm_save_state_ops *save_state_ops)
{
	uint16_t pm1_sts = clear_pm1_status();

	/*
	 * While OSPM is not active, poweroff immediately
	 * on a power button event.
	 */
	if (pm1_sts & PWRBTN_STS) {
		/* power button pressed */
		if (IS_ENABLED(CONFIG_ELOG_GSMI))
			elog_add_event(ELOG_TYPE_POWER_BUTTON);
		disable_pm1_control(-1UL);
		enable_pm1_control(SLP_EN | (SLP_TYP_S5 << SLP_TYP_SHIFT));
	}
}

void southbridge_smi_gpe0(const struct smm_save_state_ops *save_state_ops)
{
	clear_gpe_status();
}

void southbridge_smi_tco(const struct smm_save_state_ops *save_state_ops)
{
	uint32_t tco_sts = clear_tco_status();

	/* Any TCO event? */
	if (!tco_sts)
		return;

	if (tco_sts & TCO_TIMEOUT) { /* TIMEOUT */
		/* Handle TCO timeout */
		printk(BIOS_DEBUG, "TCO Timeout.\n");
	}
}

void southbridge_smi_periodic(const struct smm_save_state_ops *save_state_ops)
{
	uint32_t reg32;

	reg32 = get_smi_en();

	/* Are periodic SMIs enabled? */
	if ((reg32 & PERIODIC_EN) == 0)
		return;
	printk(BIOS_DEBUG, "Periodic SMI.\n");
}

void southbridge_smi_handler(void)
{
	int i;
	uint32_t smi_sts;
	const struct smm_save_state_ops *save_state_ops;

	/*
	 * We need to clear the SMI status registers, or we won't see what's
	 * happening in the following calls.
	 */
	smi_sts = clear_smi_status();

	save_state_ops = get_smm_save_state_ops();

	/* Call SMI sub handler for each of the status bits */
	for (i = 0; i < ARRAY_SIZE(southbridge_smi); i++) {
		if (!(smi_sts & (1 << i)))
			continue;

		if (southbridge_smi[i] != NULL) {
			southbridge_smi[i](save_state_ops);
		} else {
			printk(BIOS_DEBUG,
			       "SMI_STS[%d] occurred, but no "
			       "handler available.\n", i);
		}
	}
}

static uint32_t em64t100_smm_save_state_get_io_misc_info(void *state)
{
	em64t100_smm_state_save_area_t *smm_state = state;
	return smm_state->io_misc_info;
}

static uint64_t em64t100_smm_save_state_get_reg(void *state, enum smm_reg reg)
{
	uintptr_t value = 0;
	em64t100_smm_state_save_area_t *smm_state = state;

	switch (reg) {
	case RAX:
		value = smm_state->rax;
		break;
	case RBX:
		value = smm_state->rbx;
		break;
	case RCX:
		value = smm_state->rcx;
		break;
	case RDX:
		value = smm_state->rdx;
		break;
	default:
		break;
	}
	return value;
}

static void em64t100_smm_save_state_set_reg(void *state, enum smm_reg reg, uint64_t val)
{
	em64t100_smm_state_save_area_t *smm_state = state;
	switch (reg) {
	case RAX:
		smm_state->rax = val;
		break;
	case RBX:
		smm_state->rbx = val;
		break;
	case RCX:
		smm_state->rcx = val;
		break;
	case RDX:
		smm_state->rdx = val;
		break;
	default:
		break;
	}
}

static uint32_t em64t101_smm_save_state_get_io_misc_info(void *state)
{
	em64t101_smm_state_save_area_t *smm_state = state;
	return smm_state->io_misc_info;
}

static uint64_t em64t101_smm_save_state_get_reg(void *state, enum smm_reg reg)
{
	uintptr_t value = 0;
	em64t101_smm_state_save_area_t *smm_state = state;

	switch (reg) {
	case RAX:
		value = smm_state->rax;
		break;
	case RBX:
		value = smm_state->rbx;
		break;
	case RCX:
		value = smm_state->rcx;
		break;
	case RDX:
		value = smm_state->rdx;
		break;
	default:
		break;
	}
	return value;
}

static void em64t101_smm_save_state_set_reg(void *state, enum smm_reg reg, uint64_t val)
{
	em64t101_smm_state_save_area_t *smm_state = state;
	switch (reg) {
	case RAX:
		smm_state->rax = val;
		break;
	case RBX:
		smm_state->rbx = val;
		break;
	case RCX:
		smm_state->rcx = val;
		break;
	case RDX:
		smm_state->rdx = val;
		break;
	default:
		break;
	}
}

const struct smm_save_state_ops em64t100_smm_ops = {
	.get_io_misc_info = em64t100_smm_save_state_get_io_misc_info,
	.get_reg = em64t100_smm_save_state_get_reg,
	.set_reg = em64t100_smm_save_state_set_reg,
};

const struct smm_save_state_ops em64t101_smm_ops = {
	.get_io_misc_info = em64t101_smm_save_state_get_io_misc_info,
	.get_reg = em64t101_smm_save_state_get_reg,
	.set_reg = em64t101_smm_save_state_set_reg,
};
