/* 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 *)(uintptr_t)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 *)(uintptr_t)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 *)(uintptr_t)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 *)(uintptr_t)(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 *)(uintptr_t)(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 *)(uintptr_t)(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;
}
