/* Copyright 2019 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define pr_fmt(fmt)	"DUMP: " fmt

#include <chip.h>
#include <cpu.h>
#include <device.h>
#include <mem-map.h>
#include <mem_region.h>
#include <mem_region-malloc.h>
#include <opal.h>
#include <opal-dump.h>
#include <opal-internal.h>
#include <sbe-p9.h>
#include <skiboot.h>

#include <ccan/endian/endian.h>

#include "hdata/spira.h"

/* XXX Ideally we should use HDAT provided data (proc_dump_area->thread_size).
 *     But we are not getting this data durig boot. Hence lets reserve fixed
 *     memory for architected registers data collection.
 */
#define ARCH_REGS_DATA_SIZE_PER_CHIP	(512 * 1024)

/* Actual address of MDST and MDDT table */
#define MDST_TABLE_BASE		(SKIBOOT_BASE + MDST_TABLE_OFF)
#define MDDT_TABLE_BASE		(SKIBOOT_BASE + MDDT_TABLE_OFF)
#define PROC_DUMP_AREA_BASE	(SKIBOOT_BASE + PROC_DUMP_AREA_OFF)

static struct spira_ntuple *ntuple_mdst;
static struct spira_ntuple *ntuple_mddt;
static struct spira_ntuple *ntuple_mdrt;

static struct mpipl_metadata    *mpipl_metadata;

/* Dump metadata area */
static struct opal_mpipl_fadump *opal_mpipl_data;
static struct opal_mpipl_fadump *opal_mpipl_cpu_data;

/*
 * Number of tags passed by OPAL to kernel after MPIPL boot.
 * Currently it supports below tags:
 *   - CPU register data area
 *   - OPAL metadata area address
 *   - Kernel passed tag during MPIPL registration
 *   - Post MPIPL boot memory size
 */
#define MAX_OPAL_MPIPL_TAGS	0x04
static u64 opal_mpipl_tags[MAX_OPAL_MPIPL_TAGS];
static int opal_mpipl_max_tags = MAX_OPAL_MPIPL_TAGS;

static u64 opal_dump_addr, opal_dump_size;

static bool mpipl_enabled;

static int opal_mpipl_add_entry(u8 region, u64 src, u64 dest, u64 size)
{
	int i;
	int mdst_cnt = be16_to_cpu(ntuple_mdst->act_cnt);
	int mddt_cnt = be16_to_cpu(ntuple_mddt->act_cnt);
	struct mdst_table *mdst;
	struct mddt_table *mddt;

	if (mdst_cnt >= MDST_TABLE_SIZE / sizeof(struct mdst_table)) {
		prlog(PR_DEBUG, "MDST table is full\n");
		return OPAL_RESOURCE;
	}

	if (mddt_cnt >= MDDT_TABLE_SIZE / sizeof(struct mddt_table)) {
		prlog(PR_DEBUG, "MDDT table is full\n");
		return OPAL_RESOURCE;
	}

	/* Use relocated memory address */
	mdst = (void *)(MDST_TABLE_BASE);
	mddt = (void *)(MDDT_TABLE_BASE);

	/* Check for duplicate entry */
	for (i = 0; i < mdst_cnt; i++) {
		if (be64_to_cpu(mdst->addr) == (src | HRMOR_BIT)) {
			prlog(PR_DEBUG,
			      "Duplicate source address : 0x%llx", src);
			return OPAL_PARAMETER;
		}
		mdst++;
	}
	for (i = 0; i < mddt_cnt; i++) {
		if (be64_to_cpu(mddt->addr) == (dest | HRMOR_BIT)) {
			prlog(PR_DEBUG,
			      "Duplicate destination address : 0x%llx", dest);
			return OPAL_PARAMETER;
		}
		mddt++;
	}

	/* Add OPAL source address to MDST entry */
	mdst->addr = cpu_to_be64(src | HRMOR_BIT);
	mdst->data_region = region;
	mdst->size = cpu_to_be32(size);
	ntuple_mdst->act_cnt = cpu_to_be16(mdst_cnt + 1);

	/* Add OPAL destination address to MDDT entry */
	mddt->addr = cpu_to_be64(dest | HRMOR_BIT);
	mddt->data_region = region;
	mddt->size = cpu_to_be32(size);
	ntuple_mddt->act_cnt = cpu_to_be16(mddt_cnt + 1);

	prlog(PR_TRACE, "Added new entry. src : 0x%llx, dest : 0x%llx,"
	      " size : 0x%llx\n", src, dest, size);
	return OPAL_SUCCESS;
}

/* Remove entry from source (MDST) table */
static int opal_mpipl_remove_entry_mdst(bool remove_all, u8 region, u64 src)
{
	bool found = false;
	int i, j;
	int mdst_cnt = be16_to_cpu(ntuple_mdst->act_cnt);
	struct mdst_table *tmp_mdst;
	struct mdst_table *mdst = (void *)(MDST_TABLE_BASE);

	for (i = 0; i < mdst_cnt;) {
		if (mdst->data_region != region) {
			mdst++;
			i++;
			continue;
		}

		if (remove_all != true &&
				be64_to_cpu(mdst->addr) != (src | HRMOR_BIT)) {
			mdst++;
			i++;
			continue;
		}

		tmp_mdst = mdst;
		memset(tmp_mdst, 0, sizeof(struct mdst_table));

		for (j = i; j < mdst_cnt - 1; j++) {
			memcpy((void *)tmp_mdst,
			       (void *)(tmp_mdst + 1), sizeof(struct mdst_table));
			tmp_mdst++;
			memset(tmp_mdst, 0, sizeof(struct mdst_table));
		}

		mdst_cnt--;

		if (remove_all == false) {
			found = true;
			break;
		}
	}  /* end - for loop */

	ntuple_mdst->act_cnt = cpu_to_be16((u16)mdst_cnt);

	if (remove_all == false && found == false) {
		prlog(PR_DEBUG,
		      "Source address [0x%llx] not found in MDST table\n", src);
		return OPAL_PARAMETER;
	}

	return OPAL_SUCCESS;
}

/* Remove entry from destination (MDDT) table */
static int opal_mpipl_remove_entry_mddt(bool remove_all, u8 region, u64 dest)
{
	bool found = false;
	int i, j;
	int mddt_cnt = be16_to_cpu(ntuple_mddt->act_cnt);
	struct mddt_table *tmp_mddt;
	struct mddt_table *mddt = (void *)(MDDT_TABLE_BASE);

	for (i = 0; i < mddt_cnt;) {
		if (mddt->data_region != region) {
			mddt++;
			i++;
			continue;
		}

		if (remove_all != true &&
				be64_to_cpu(mddt->addr) != (dest | HRMOR_BIT)) {
			mddt++;
			i++;
			continue;
		}

		tmp_mddt = mddt;
		memset(tmp_mddt, 0, sizeof(struct mddt_table));

		for (j = i; j < mddt_cnt - 1; j++) {
			memcpy((void *)tmp_mddt,
			       (void *)(tmp_mddt + 1), sizeof(struct mddt_table));
			tmp_mddt++;
			memset(tmp_mddt, 0, sizeof(struct mddt_table));
		}

		mddt_cnt--;

		if (remove_all == false) {
			found = true;
			break;
		}
	}  /* end - for loop */

	ntuple_mddt->act_cnt = cpu_to_be16((u16)mddt_cnt);

	if (remove_all == false && found == false) {
		prlog(PR_DEBUG,
		      "Dest address [0x%llx] not found in MDDT table\n", dest);
		return OPAL_PARAMETER;
	}

	return OPAL_SUCCESS;
}

/* Register for OPAL dump.  */
static void opal_mpipl_register(void)
{
	u64 arch_regs_dest, arch_regs_size;
	struct proc_dump_area *proc_dump = (void *)(PROC_DUMP_AREA_BASE);

	/* Add OPAL reservation detail to MDST/MDDT table */
	opal_mpipl_add_entry(DUMP_REGION_OPAL_MEMORY,
			     SKIBOOT_BASE, opal_dump_addr, opal_dump_size);

	/* Thread size check */
	if (proc_dump->thread_size != 0) {
		prlog(PR_INFO, "Thread register entry size is available, "
		      "but not supported.\n");
	}

	/* Reserve memory used to capture architected register state */
	arch_regs_dest = opal_dump_addr + opal_dump_size;
	arch_regs_size = nr_chips() * ARCH_REGS_DATA_SIZE_PER_CHIP;
	proc_dump->alloc_addr = cpu_to_be64(arch_regs_dest | HRMOR_BIT);
	proc_dump->alloc_size = cpu_to_be32(arch_regs_size);
	prlog(PR_NOTICE, "Architected register dest addr : 0x%llx, "
	      "size : 0x%llx\n", arch_regs_dest, arch_regs_size);
}

static int payload_mpipl_register(u64 src, u64 dest, u64 size)
{
	if (!opal_addr_valid((void *)src)) {
		prlog(PR_DEBUG, "Invalid source address [0x%llx]\n", src);
		return OPAL_PARAMETER;
	}

	if (!opal_addr_valid((void *)dest)) {
		prlog(PR_DEBUG, "Invalid dest address [0x%llx]\n", dest);
		return OPAL_PARAMETER;
	}

	if (size <= 0) {
		prlog(PR_DEBUG, "Invalid size [0x%llx]\n", size);
		return OPAL_PARAMETER;
	}

	return opal_mpipl_add_entry(DUMP_REGION_KERNEL, src, dest, size);
}

static int payload_mpipl_unregister(u64 src, u64 dest)
{
	int rc;

	/* Remove src from MDST table */
	rc = opal_mpipl_remove_entry_mdst(false, DUMP_REGION_KERNEL, src);
	if (rc)
		return rc;

	/* Remove dest from MDDT table */
	rc = opal_mpipl_remove_entry_mddt(false, DUMP_REGION_KERNEL, dest);
	return rc;
}

static int payload_mpipl_unregister_all(void)
{
	opal_mpipl_remove_entry_mdst(true, DUMP_REGION_KERNEL, 0);
	opal_mpipl_remove_entry_mddt(true, DUMP_REGION_KERNEL, 0);

	return OPAL_SUCCESS;
}

static int64_t opal_mpipl_update(enum opal_mpipl_ops ops,
				 u64 src, u64 dest, u64 size)
{
	int rc;
	void *skiboot_constant_addr mdrt_table_base_addr = (void *) MDRT_TABLE_BASE;

	switch (ops) {
	case OPAL_MPIPL_ADD_RANGE:
		rc = payload_mpipl_register(src, dest, size);
		if (!rc)
			prlog(PR_NOTICE, "Payload registered for MPIPL\n");
		break;
	case OPAL_MPIPL_REMOVE_RANGE:
		rc = payload_mpipl_unregister(src, dest);
		if (!rc) {
			prlog(PR_NOTICE, "Payload removed entry from MPIPL."
			      "[src : 0x%llx, dest : 0x%llx]\n", src, dest);
		}
		break;
	case OPAL_MPIPL_REMOVE_ALL:
		rc = payload_mpipl_unregister_all();
		if (!rc)
			prlog(PR_NOTICE, "Payload unregistered for MPIPL\n");
		break;
	case OPAL_MPIPL_FREE_PRESERVED_MEMORY:
		/* Clear tags */
		memset(&opal_mpipl_tags, 0, (sizeof(u64) * MAX_OPAL_MPIPL_TAGS));
		opal_mpipl_max_tags = 0;
		/* Release memory */
		free(opal_mpipl_data);
		opal_mpipl_data = NULL;
		free(opal_mpipl_cpu_data);
		opal_mpipl_cpu_data = NULL;
		/* Clear MDRT table */
		memset(mdrt_table_base_addr, 0, MDRT_TABLE_SIZE);
		/* Set MDRT count to max allocated count */
		ntuple_mdrt->act_cnt = cpu_to_be16(MDRT_TABLE_SIZE / sizeof(struct mdrt_table));
		rc = OPAL_SUCCESS;
		prlog(PR_NOTICE, "Payload Invalidated MPIPL\n");
		break;
	default:
		prlog(PR_DEBUG, "Unsupported MPIPL update operation : 0x%x\n", ops);
		rc = OPAL_PARAMETER;
		break;
	}

	return rc;
}

static int64_t opal_mpipl_register_tag(enum opal_mpipl_tags tag,
				       uint64_t tag_val)
{
	int rc = OPAL_SUCCESS;

	switch (tag) {
	case OPAL_MPIPL_TAG_BOOT_MEM:
		if (tag_val <= 0 || tag_val > top_of_ram) {
			prlog(PR_DEBUG, "Payload sent invalid boot mem size"
			      " :  0x%llx\n", tag_val);
			rc = OPAL_PARAMETER;
		} else {
			mpipl_metadata->boot_mem_size = tag_val;
			prlog(PR_NOTICE, "Boot mem size : 0x%llx\n", tag_val);
		}
		break;
	case OPAL_MPIPL_TAG_KERNEL:
		mpipl_metadata->kernel_tag = tag_val;
		prlog(PR_NOTICE, "Payload sent metadata tag : 0x%llx\n", tag_val);
		break;
	default:
		prlog(PR_DEBUG, "Payload sent unsupported tag : 0x%x\n", tag);
		rc = OPAL_PARAMETER;
		break;
	}
	return rc;
}

static uint64_t opal_mpipl_query_tag(enum opal_mpipl_tags tag, __be64 *tag_val)
{
	if (!opal_addr_valid(tag_val)) {
		prlog(PR_DEBUG, "Invalid tag address\n");
		return OPAL_PARAMETER;
	}

	if (tag >= opal_mpipl_max_tags)
		return OPAL_PARAMETER;

	*tag_val = cpu_to_be64(opal_mpipl_tags[tag]);
	return OPAL_SUCCESS;
}

static inline void post_mpipl_get_preserved_tags(void)
{
	if (mpipl_metadata->kernel_tag)
		opal_mpipl_tags[OPAL_MPIPL_TAG_KERNEL] = mpipl_metadata->kernel_tag;
	if (mpipl_metadata->boot_mem_size)
		opal_mpipl_tags[OPAL_MPIPL_TAG_BOOT_MEM] = mpipl_metadata->boot_mem_size;
}

static void post_mpipl_arch_regs_data(void)
{
	struct proc_dump_area *proc_dump = (void *)(PROC_DUMP_AREA_BASE);

	if (proc_dump->dest_addr == 0) {
		prlog(PR_DEBUG, "Invalid CPU registers destination address\n");
		return;
	}

	if (proc_dump->act_size == 0) {
		prlog(PR_DEBUG, "Invalid CPU registers destination size\n");
		return;
	}

	opal_mpipl_cpu_data = zalloc(sizeof(struct opal_mpipl_fadump) +
				sizeof(struct opal_mpipl_region));
	if (!opal_mpipl_cpu_data) {
		prlog(PR_ERR, "Failed to allocate memory\n");
		return;
	}

	/* Fill CPU register details */
	opal_mpipl_cpu_data->version = OPAL_MPIPL_VERSION;
	opal_mpipl_cpu_data->cpu_data_version = cpu_to_be32((u32)proc_dump->version);
	opal_mpipl_cpu_data->cpu_data_size = proc_dump->thread_size;
	opal_mpipl_cpu_data->region_cnt = cpu_to_be32(1);

	opal_mpipl_cpu_data->region[0].src  = proc_dump->dest_addr & ~(cpu_to_be64(HRMOR_BIT));
	opal_mpipl_cpu_data->region[0].dest = proc_dump->dest_addr & ~(cpu_to_be64(HRMOR_BIT));
	opal_mpipl_cpu_data->region[0].size = cpu_to_be64(be32_to_cpu(proc_dump->act_size));

	/* Update tag */
	opal_mpipl_tags[OPAL_MPIPL_TAG_CPU] = (u64)opal_mpipl_cpu_data;
}

static void post_mpipl_get_opal_data(void)
{
	struct mdrt_table *mdrt = (void *)(MDRT_TABLE_BASE);
	int i, j = 0, count = 0;
	int mdrt_cnt = be16_to_cpu(ntuple_mdrt->act_cnt);
	struct opal_mpipl_region *region;

	/* Count OPAL dump regions */
	for (i = 0; i < mdrt_cnt; i++) {
		if (mdrt->data_region == DUMP_REGION_OPAL_MEMORY)
			count++;
		mdrt++;
	}

	if (count == 0) {
		prlog(PR_INFO, "OPAL dump is not available\n");
		return;
	}

	opal_mpipl_data = zalloc(sizeof(struct opal_mpipl_fadump) +
				 count * sizeof(struct opal_mpipl_region));
	if (!opal_mpipl_data) {
		prlog(PR_ERR, "Failed to allocate memory\n");
		return;
	}

	/* Fill OPAL dump details */
	opal_mpipl_data->version = OPAL_MPIPL_VERSION;
	opal_mpipl_data->crashing_pir = cpu_to_be32(mpipl_metadata->crashing_pir);
	opal_mpipl_data->region_cnt = cpu_to_be32(count);
	region = opal_mpipl_data->region;

	mdrt = (void *)(MDRT_TABLE_BASE);
	for (i = 0; i < mdrt_cnt; i++) {
		if (mdrt->data_region != DUMP_REGION_OPAL_MEMORY) {
			mdrt++;
			continue;
		}

		region[j].src  = mdrt->src_addr  & ~(cpu_to_be64(HRMOR_BIT));
		region[j].dest = mdrt->dest_addr & ~(cpu_to_be64(HRMOR_BIT));
		region[j].size = cpu_to_be64(be32_to_cpu(mdrt->size));

		prlog(PR_NOTICE, "OPAL reserved region %d - src : 0x%llx, "
		      "dest : 0x%llx, size : 0x%llx\n", j,
		      be64_to_cpu(region[j].src), be64_to_cpu(region[j].dest),
		      be64_to_cpu(region[j].size));

		mdrt++;
		j++;
		if (j == count)
			break;
	}

	opal_mpipl_tags[OPAL_MPIPL_TAG_OPAL] = (u64)opal_mpipl_data;
}

void opal_mpipl_save_crashing_pir(void)
{
	if (!is_mpipl_enabled())
		return;

	mpipl_metadata->crashing_pir = this_cpu()->pir;
	prlog(PR_NOTICE, "Crashing PIR = 0x%x\n", this_cpu()->pir);
}

void opal_mpipl_reserve_mem(void)
{
	struct dt_node *opal_node, *dump_node;
	u64 arch_regs_dest, arch_regs_size;

	opal_node = dt_find_by_path(dt_root, "ibm,opal");
	if (!opal_node)
		return;

	dump_node = dt_find_by_path(opal_node, "dump");
	if (!dump_node)
		return;

	/* Calculcate and Reserve OPAL dump destination memory */
	opal_dump_size = SKIBOOT_SIZE + (cpu_max_pir + 1) * STACK_SIZE;
	opal_dump_addr = SKIBOOT_BASE + opal_dump_size;
	mem_reserve_fw("ibm,firmware-dump",
		       opal_dump_addr, opal_dump_size);

	/* Reserve memory to capture CPU register data */
	arch_regs_dest = opal_dump_addr + opal_dump_size;
	arch_regs_size = nr_chips() * ARCH_REGS_DATA_SIZE_PER_CHIP;
	mem_reserve_fw("ibm,firmware-arch-registers",
		       arch_regs_dest, arch_regs_size);
}

bool is_mpipl_enabled(void)
{
	return mpipl_enabled;
}

void opal_mpipl_init(void)
{
	void *skiboot_constant_addr mdst_base = (void *)MDST_TABLE_BASE;
	void *skiboot_constant_addr mddt_base = (void *)MDDT_TABLE_BASE;
	struct dt_node *dump_node;

	dump_node = dt_find_by_path(opal_node, "dump");
	if (!dump_node)
		return;

	/* Get MDST and MDDT ntuple from SPIRAH */
	ntuple_mdst = &(spirah.ntuples.mdump_src);
	ntuple_mddt = &(spirah.ntuples.mdump_dst);
	ntuple_mdrt = &(spirah.ntuples.mdump_res);

	/* Get metadata area pointer */
	mpipl_metadata = (void *)(DUMP_METADATA_AREA_BASE);

	if (dt_find_property(dump_node, "mpipl-boot")) {
		disable_fast_reboot("MPIPL Boot");

		post_mpipl_get_preserved_tags();
		post_mpipl_get_opal_data();
		post_mpipl_arch_regs_data();
	}

	/* Clear OPAL metadata area */
	if (sizeof(struct mpipl_metadata) > DUMP_METADATA_AREA_SIZE) {
		prlog(PR_ERR, "INSUFFICIENT OPAL METADATA AREA\n");
		prlog(PR_ERR, "INCREASE OPAL MEDTADATA AREA SIZE\n");
		assert(false);
	}
	memset(mpipl_metadata, 0, sizeof(struct mpipl_metadata));

	/* Clear MDST and MDDT table */
	memset(mdst_base, 0, MDST_TABLE_SIZE);
	ntuple_mdst->act_cnt = 0;
	memset(mddt_base, 0, MDDT_TABLE_SIZE);
	ntuple_mddt->act_cnt = 0;

	opal_mpipl_register();

	/* Send OPAL relocated base address to SBE */
	p9_sbe_send_relocated_base(SKIBOOT_BASE);

	/* OPAL API for MPIPL update */
	opal_register(OPAL_MPIPL_UPDATE, opal_mpipl_update, 4);
	opal_register(OPAL_MPIPL_REGISTER_TAG, opal_mpipl_register_tag, 2);
	opal_register(OPAL_MPIPL_QUERY_TAG, opal_mpipl_query_tag, 2);

	/* Enable MPIPL */
	mpipl_enabled = true;
}
