/* SPDX-License-Identifier: GPL-2.0-only */

#include <arch/bert_storage.h>
#include <console/console.h>
#include <cpu/cpu.h>
#include <cpu/intel/cpu_ids.h>
#include <delay.h>
#include <device/pci_ops.h>
#include <intelblocks/crashlog.h>
#include <intelblocks/pmc_ipc.h>
#include <soc/crashlog.h>
#include <soc/iomap.h>
#include <soc/pci_devs.h>
#include <string.h>

#define CONTROL_INTERFACE_OFFSET	0x5
#define CRASHLOG_PUNIT_STORAGE_OFF_MASK	BIT(24)
#define CRASHLOG_RE_ARM_STATUS_MASK	BIT(25)
#define CRASHLOG_CONSUMED_MASK		BIT(31)

/* global crashLog info */
static bool m_pmc_crashLog_support;
static bool m_pmc_crashLog_present;
static bool m_cpu_crashLog_support;
static bool m_cpu_crashLog_present;
static u32 m_pmc_crashLog_size;
static u32 m_cpu_crashLog_size;
static u32 cpu_crash_version;
static pmc_ipc_discovery_buf_t discovery_buf;
static pmc_crashlog_desc_table_t descriptor_table;
static tel_crashlog_devsc_cap_t cpu_cl_devsc_cap;
static cpu_crashlog_discovery_table_t cpu_cl_disc_tab;
static u32 disc_tab_addr;

static u64 get_disc_tab_header(void)
{
	return read64((void *)disc_tab_addr);
}

/* Get the SRAM BAR. */
static uintptr_t get_sram_bar(pci_devfn_t sram_devfn)
{
	uintptr_t sram_bar;
	const struct device *dev;
	struct resource *res;

	dev = pcidev_path_on_root(sram_devfn);
	if (!dev) {
		printk(BIOS_ERR, "device: 0x%x not found!\n", sram_devfn);
		return 0;
	}

	res = probe_resource(dev, PCI_BASE_ADDRESS_0);
	if (!res) {
		printk(BIOS_ERR, "SOC SRAM device not found!\n");
		return 0;
	}

	/* Get the base address of the resource */
	sram_bar = res->base;

	return sram_bar;
}

static void configure_sram(const struct device *sram_dev, u32 base_addr)
{
	pci_update_config16(sram_dev, PCI_COMMAND, ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY), 0);

	/* Program BAR 0 and enable command register memory space decoding */
	pci_write_config32(sram_dev, PCI_BASE_ADDRESS_0, base_addr);
	pci_or_config16(sram_dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
}

void cl_get_pmc_sram_data(cl_node_t *head)
{
	u32 pmc_sram_base = cl_get_cpu_tmp_bar();
	u32 ioe_sram_base = get_sram_bar(PCI_DEVFN_IOE_SRAM);
	u32 pmc_crashLog_size = cl_get_pmc_record_size();
	cl_node_t *cl_cur = head;

	if (!pmc_crashLog_size) {
		printk(BIOS_ERR, "No PMC crashlog records\n");
		return;
	}

	if (!pmc_sram_base) {
		printk(BIOS_ERR, "PMC SRAM base not valid\n");
		return;
	}

	if (!ioe_sram_base) {
		printk(BIOS_ERR, "IOE SRAM base not valid\n");
		return;
	}

	configure_sram(PCI_DEV_IOE_SRAM, ioe_sram_base);

	if (!cl_pmc_sram_has_mmio_access())
		return;

	if (!cl_ioe_sram_has_mmio_access())
		return;

	printk(BIOS_DEBUG, "PMC crashLog size : 0x%x\n", pmc_crashLog_size);

	/* goto tail node */
	while (cl_cur && cl_cur->next) {
		cl_cur = cl_cur->next;
	}

	/* process crashlog records */
	for (int i = 0; i < descriptor_table.numb_regions + 1; i++) {

		u32 sram_base = 0;
		bool pmc_sram = true;
		printk(BIOS_DEBUG, "Region[0x%x].Tag=0x%x offset=0x%x, size=0x%x\n",
				i,
				descriptor_table.regions[i].bits.assign_tag,
				descriptor_table.regions[i].bits.offset,
				descriptor_table.regions[i].bits.size);

		if (!descriptor_table.regions[i].bits.size)
			continue;

		/*
		 * Region with metadata TAG contains information about BDF entry for SOC PMC SRAM
		 * and IOE SRAM. We don't need to parse this as we already define BDFs in
		 * soc/pci_devs.h for these SRAMs. Also we need to skip this region as it does not
		 * contain any crashlog data.
		 */
		if (descriptor_table.regions[i].bits.assign_tag ==
				CRASHLOG_DESCRIPTOR_TABLE_TAG_META) {
			pmc_crashLog_size -= descriptor_table.regions[i].bits.size *
						sizeof(u32);
			printk(BIOS_DEBUG, "Found metadata tag. PMC crashlog size adjusted to: 0x%x\n",
					pmc_crashLog_size);
			continue;
		} else {
			if (descriptor_table.regions[i].bits.assign_tag ==
					CRASHLOG_DESCRIPTOR_TABLE_TAG_SOC)
				sram_base = pmc_sram_base;
			else if (descriptor_table.regions[i].bits.assign_tag ==
					CRASHLOG_DESCRIPTOR_TABLE_TAG_IOE)
				sram_base = ioe_sram_base;
			else
				continue;

			cl_node_t *cl_node = malloc_cl_node(descriptor_table.regions[i].bits.size);

			if (!cl_node) {
				printk(BIOS_DEBUG, "failed to allocate cl_node [region = %d]\n", i);
				goto pmc_send_re_arm_after_reset;
			}

			if (cl_copy_data_from_sram(sram_base,
						descriptor_table.regions[i].bits.offset,
						descriptor_table.regions[i].bits.size,
						cl_node->data,
						i,
						pmc_sram)) {
				cl_cur->next = cl_node;
				cl_cur = cl_cur->next;
			} else {
				/* coping data from sram failed */
				pmc_crashLog_size -= descriptor_table.regions[i].bits.size *
									sizeof(u32);
				printk(BIOS_DEBUG, "PMC crashlog size adjusted to: 0x%x\n",
							pmc_crashLog_size);
				/* free cl_node */
				free_cl_node(cl_node);
			}
		}
	}

	update_new_pmc_crashlog_size(&pmc_crashLog_size);

pmc_send_re_arm_after_reset:
	/* when bit 7 of discov cmd resp is set -> bit 2 of size field */
	cl_pmc_re_arm_after_reset();

	/* Clear the SSRAM region after copying the error log */
	cl_pmc_clear();
}

bool pmc_cl_discovery(void)
{
	u32 bar_addr = 0, desc_table_addr = 0;

	const struct pmc_ipc_buffer req = { 0 };
	struct pmc_ipc_buffer res;
	uint32_t cmd_reg;
	int r;

	cmd_reg = pmc_make_ipc_cmd(PMC_IPC_CMD_CRASHLOG,
				PMC_IPC_CMD_ID_CRASHLOG_DISCOVERY,
				PMC_IPC_CMD_SIZE_SHIFT);
	printk(BIOS_DEBUG, "cmd_reg from pmc_make_ipc_cmd %d in %s\n", cmd_reg, __func__);

	r = pmc_send_ipc_cmd(cmd_reg, &req, &res);

	if (r < 0) {
		printk(BIOS_ERR, "pmc_send_ipc_cmd failed in %s\n", __func__);
		return false;
	}
	discovery_buf.conv_val_64_bits = ((u64)res.buf[1] << 32) | res.buf[0];

	if ((discovery_buf.conv_bits64.supported != 1) ||
		(discovery_buf.conv_bits64.discov_mechanism == 0) ||
			(discovery_buf.conv_bits64.crash_dis_sts == 1)) {
		printk(BIOS_INFO, "PCH crashlog feature not supported.\n");
		m_pmc_crashLog_support = false;
		m_pmc_crashLog_size = 0;
		printk(BIOS_DEBUG, "discovery_buf supported: %d, mechanism: %d, CrashDisSts: %d\n",
			discovery_buf.conv_bits64.supported,
			discovery_buf.conv_bits64.discov_mechanism,
			discovery_buf.conv_bits64.crash_dis_sts);
		return false;
	}

	printk(BIOS_INFO, "PMC crashlog feature is supported.\n");
	m_pmc_crashLog_support = true;

	/* Program BAR 0 and enable command register memory space decoding */
	bar_addr = get_sram_bar(PCI_DEVFN_SRAM);
	if (bar_addr == 0) {
		printk(BIOS_ERR, "PCH SRAM not available, crashlog feature can't be enabled.\n");
		return false;
	}

	configure_sram(PCI_DEV_SRAM, bar_addr);

	desc_table_addr = bar_addr + discovery_buf.conv_bits64.desc_tabl_offset;
	m_pmc_crashLog_size = pmc_cl_gen_descriptor_table(desc_table_addr,
								&descriptor_table);
	printk(BIOS_DEBUG, "PMC CrashLog size in discovery mode: 0x%X\n",
					m_pmc_crashLog_size);
	m_pmc_crashLog_present = m_pmc_crashLog_size > 0;

	return true;
}

u32 cl_get_cpu_bar_addr(void)
{
	u32 base_addr = 0;
	if (cpu_cl_devsc_cap.discovery_data.fields.t_bir_q == TEL_DVSEC_TBIR_BAR0) {
		base_addr = pci_read_config32(PCI_DEV_TELEMETRY, PCI_BASE_ADDRESS_0) &
				~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
	} else if (cpu_cl_devsc_cap.discovery_data.fields.t_bir_q == TEL_DVSEC_TBIR_BAR1) {
		base_addr = pci_read_config32(PCI_DEV_TELEMETRY, PCI_BASE_ADDRESS_1) &
				~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
	} else {
		printk(BIOS_ERR, "Invalid TEL_CFG_BAR value %d, discovery failure expected.\n",
			cpu_cl_devsc_cap.discovery_data.fields.t_bir_q);
	}

	return base_addr;
}

u32 cl_get_cpu_tmp_bar(void)
{
	return get_sram_bar(PCI_DEVFN_SRAM);
}

bool  cl_pmc_sram_has_mmio_access(void)
{
	if (pci_read_config16(PCI_DEV_SRAM, PCI_VENDOR_ID) == 0xFFFF) {
		printk(BIOS_ERR, "PMC SSRAM PCI device disabled. Can be enabled in device tree.\n");
		return false;
	}

	return true;
}

bool  cl_ioe_sram_has_mmio_access(void)
{
	if (pci_read_config16(PCI_DEV_IOE_SRAM, PCI_VENDOR_ID) == 0xFFFF) {
		printk(BIOS_ERR, "IOE SSRAM PCI device disabled. Can be enabled in device tree.\n");
		return false;
	}
	return true;
}

static bool cpu_cl_get_capability(tel_crashlog_devsc_cap_t *cl_devsc_cap)
{
	cl_devsc_cap->cap_data.data = pci_read_config32(PCI_DEV_TELEMETRY,
						TEL_DVSEC_OFFSET + TEL_DVSEC_PCIE_CAP_ID);
	if (cl_devsc_cap->cap_data.fields.pcie_cap_id != TELEMETRY_EXTENDED_CAP_ID) {
		printk(BIOS_DEBUG, "Read ID for Telemetry: 0x%x differs from expected: 0x%x\n",
		       cl_devsc_cap->cap_data.fields.pcie_cap_id, TELEMETRY_EXTENDED_CAP_ID);
		return false;
	}

	/* walk through the entries until crashLog entry */
	cl_devsc_cap->devsc_data.data_32[1] = pci_read_config32(PCI_DEV_TELEMETRY, TEL_DVSEV_ID);
	int new_offset = 0;
	while (cl_devsc_cap->devsc_data.fields.devsc_id != CRASHLOG_DVSEC_ID) {
		if (cl_devsc_cap->cap_data.fields.next_cap_offset == 0
		     || cl_devsc_cap->cap_data.fields.next_cap_offset == 0xFFFF) {
			printk(BIOS_DEBUG, "Read invalid pcie_cap_id value: 0x%x\n",
			       cl_devsc_cap->cap_data.fields.pcie_cap_id);
			return false;
		}
		new_offset = cl_devsc_cap->cap_data.fields.next_cap_offset;
		cl_devsc_cap->cap_data.data = pci_read_config32(PCI_DEV_TELEMETRY,
						new_offset + TEL_DVSEC_PCIE_CAP_ID);
		cl_devsc_cap->devsc_data.data_32[1] = pci_read_config32(PCI_DEV_TELEMETRY,
							new_offset + TEL_DVSEV_ID);
	}
	cpu_crash_version = cl_devsc_cap->devsc_data.fields.devsc_ver;

	cl_devsc_cap->discovery_data.data = pci_read_config32(PCI_DEV_TELEMETRY, new_offset
						+ TEL_DVSEV_DISCOVERY_TABLE_OFFSET);

	return true;
}

static u32 get_disc_table_offset(void)
{
	u32 offset = cpu_cl_devsc_cap.discovery_data.fields.discovery_table_offset;
	if (cpu_get_cpuid() >= CPUID_METEORLAKE_B0) {
		offset <<= 3;
		printk(BIOS_DEBUG, "adjusted cpu discovery table offset: 0x%x\n", offset);
	}

	return offset;
}

static bool is_crashlog_data_valid(u32 dw0)
{
	return (dw0 != 0x0 && dw0 != INVALID_CRASHLOG_RECORD);
}

static bool cpu_cl_gen_discovery_table(void)
{
	u32 bar_addr = cl_get_cpu_bar_addr();

	if (!bar_addr)
		return false;

	disc_tab_addr = bar_addr + get_disc_table_offset();

	u32 dw0 = read32((u32 *)disc_tab_addr);
	if (!is_crashlog_data_valid(dw0))
		return false;

	memset(&cpu_cl_disc_tab, 0, sizeof(cpu_crashlog_discovery_table_t));
	cpu_cl_disc_tab.header.data = get_disc_tab_header();
	printk(BIOS_DEBUG, "cpu_crashlog_discovery_table buffer count: 0x%x\n",
		cpu_cl_disc_tab.header.fields.count);

	int cur_offset = 0;
	for (int i = 0; i < cpu_cl_disc_tab.header.fields.count; i++) {
		cur_offset = 8 + 24 * i;

		dw0 = read32((u32 *)disc_tab_addr + cur_offset);
		if (!is_crashlog_data_valid(dw0))
			continue;

		if (dw0 & CRASHLOG_CONSUMED_MASK) {
			printk(BIOS_DEBUG, "cpu crashlog records already consumed."
						"id: 0x%x dw0: 0x%x\n", i, dw0);
			break;
		}

		cpu_cl_disc_tab.buffers[i].data = read64((void *)(disc_tab_addr + cur_offset));
		printk(BIOS_DEBUG, "cpu_crashlog_discovery_table buffer: 0x%x size: "
			"0x%x offset: 0x%x\n", i,  cpu_cl_disc_tab.buffers[i].fields.size,
			cpu_cl_disc_tab.buffers[i].fields.offset);
		m_cpu_crashLog_size += cpu_cl_disc_tab.buffers[i].fields.size * sizeof(u32);
	}

	if (m_cpu_crashLog_size > 0)
		m_cpu_crashLog_present = true;
	else
		m_cpu_crashLog_present = false;

	return true;
}

bool cpu_cl_discovery(void)
{
	memset(&cpu_cl_devsc_cap, 0, sizeof(tel_crashlog_devsc_cap_t));

	if (!cpu_cl_get_capability(&cpu_cl_devsc_cap)) {
		printk(BIOS_ERR, "CPU crashlog capability not found.\n");
		m_cpu_crashLog_support = false;
		return false;
	}

	m_cpu_crashLog_support = true;

	if (!cpu_cl_gen_discovery_table()) {
		printk(BIOS_ERR, "CPU crashlog discovery table not valid.\n");
		m_cpu_crashLog_present = false;
		return false;
	}

	return true;
}

void reset_discovery_buffers(void)
{
	memset(&discovery_buf, 0, sizeof(pmc_ipc_discovery_buf_t));
	memset(&descriptor_table, 0, sizeof(pmc_crashlog_desc_table_t));
	memset(&cpu_cl_devsc_cap, 0, sizeof(tel_crashlog_devsc_cap_t));
}

int cl_get_total_data_size(void)
{
	printk(BIOS_DEBUG, "crashlog size:pmc-0x%x, cpu-0x%x\n",
			m_pmc_crashLog_size, m_cpu_crashLog_size);
	return m_pmc_crashLog_size + m_cpu_crashLog_size;
}

static u32 get_control_status_interface(void)
{
	if (disc_tab_addr)
		return (disc_tab_addr + CONTROL_INTERFACE_OFFSET * sizeof(u32));
	return 0;
}

int cpu_cl_clear_data(void)
{
	return 0;
}

static bool wait_and_check(u32 bit_mask)
{
	u32 stall_cnt = 0;

	do {
		cpu_cl_disc_tab.header.data = get_disc_tab_header();
		udelay(CPU_CRASHLOG_WAIT_STALL);
		stall_cnt++;
	} while (((cpu_cl_disc_tab.header.data & bit_mask) == 0) &&
			((stall_cnt * CPU_CRASHLOG_WAIT_STALL) < CPU_CRASHLOG_WAIT_TIMEOUT));

	return (cpu_cl_disc_tab.header.data & bit_mask);
}

void cpu_cl_rearm(void)
{
	u32 ctrl_sts_intfc_addr = get_control_status_interface();

	if (!ctrl_sts_intfc_addr) {
		printk(BIOS_ERR, "CPU crashlog control and status interface address not valid\n");
		return;
	}

	/* Rearm the CPU crashlog. Crashlog does not get collected if rearming fails */
	cl_punit_control_interface_t punit_ctrl_intfc;
	memset(&punit_ctrl_intfc, 0, sizeof(cl_punit_control_interface_t));
	punit_ctrl_intfc.fields.set_re_arm = 1;
	write32((u32 *)(ctrl_sts_intfc_addr), punit_ctrl_intfc.data);

	if (!wait_and_check(CRASHLOG_RE_ARM_STATUS_MASK))
		printk(BIOS_ERR, "CPU crashlog re_arm not asserted\n");
	else
		printk(BIOS_DEBUG, "CPU crashlog re_arm asserted\n");
}

void cpu_cl_cleanup(void)
{
	/* Perform any SOC specific cleanup after reading the crashlog data from SRAM */
	u32 ctrl_sts_intfc_addr = get_control_status_interface();

	if (!ctrl_sts_intfc_addr) {
		printk(BIOS_ERR, "CPU crashlog control and status interface address not valid\n");
		return;
	}

	/* If storage-off is supported, turn off the PUNIT SRAM
	 * stroage to save power. This clears crashlog records also.
	 */

	if (!cpu_cl_disc_tab.header.fields.storage_off_support) {
		printk(BIOS_INFO, "CPU crashlog storage_off not supported\n");
		return;
	}

	cl_punit_control_interface_t punit_ctrl_intfc;
	memset(&punit_ctrl_intfc, 0, sizeof(cl_punit_control_interface_t));
	punit_ctrl_intfc.fields.set_storage_off = 1;
	write32((u32 *)(ctrl_sts_intfc_addr), punit_ctrl_intfc.data);

	if (!wait_and_check(CRASHLOG_PUNIT_STORAGE_OFF_MASK))
		printk(BIOS_ERR, "CPU crashlog storage_off not asserted\n");
	else
		printk(BIOS_DEBUG, "CPU crashlog storage_off asserted\n");
}

pmc_ipc_discovery_buf_t cl_get_pmc_discovery_buf(void)
{
	return discovery_buf;
}

pmc_crashlog_desc_table_t cl_get_pmc_descriptor_table(void)
{
	return descriptor_table;
}

int cl_get_pmc_record_size(void)
{
	return m_pmc_crashLog_size;
}

int cl_get_cpu_record_size(void)
{
	return m_cpu_crashLog_size;
}

bool cl_cpu_data_present(void)
{
	return m_cpu_crashLog_present;
}

bool cl_pmc_data_present(void)
{
	return m_pmc_crashLog_present;
}

bool cpu_crashlog_support(void)
{
	return m_cpu_crashLog_support;
}

bool pmc_crashlog_support(void)
{
	return m_pmc_crashLog_support;
}

void update_new_pmc_crashlog_size(u32 *pmc_crash_size)
{
	m_pmc_crashLog_size = *pmc_crash_size;
}

cpu_crashlog_discovery_table_t cl_get_cpu_discovery_table(void)
{
	return cpu_cl_disc_tab;
}

void update_new_cpu_crashlog_size(u32 *cpu_crash_size)
{
	m_cpu_crashLog_size = *cpu_crash_size;
}
