// SPDX-License-Identifier: GPL-2.0-only
/*
 * APEI Boot Error Record Table (BERT) support
 *
 * Copyright 2011 Intel Corp.
 *   Author: Huang Ying <ying.huang@intel.com>
 *
 * Under normal circumstances, when a hardware error occurs, the error
 * handler receives control and processes the error. This gives OSPM a
 * chance to process the error condition, report it, and optionally attempt
 * recovery. In some cases, the system is unable to process an error.
 * For example, system firmware or a management controller may choose to
 * reset the system or the system might experience an uncontrolled crash
 * or reset.The boot error source is used to report unhandled errors that
 * occurred in a previous boot. This mechanism is described in the BERT
 * table.
 *
 * For more information about BERT, please refer to ACPI Specification
 * version 4.0, section 17.3.1
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <linux/io.h>

#include "apei-internal.h"

#undef pr_fmt
#define pr_fmt(fmt) "BERT: " fmt
#define ACPI_BERT_PRINT_MAX_LEN 1024

static int bert_disable;

static void __init bert_print_all(struct acpi_bert_region *region,
				  unsigned int region_len)
{
	struct acpi_hest_generic_status *estatus =
		(struct acpi_hest_generic_status *)region;
	int remain = region_len;
	u32 estatus_len;

	while (remain >= sizeof(struct acpi_bert_region)) {
		estatus_len = cper_estatus_len(estatus);
		if (remain < estatus_len) {
			pr_err(FW_BUG "Truncated status block (length: %u).\n",
			       estatus_len);
			return;
		}

		/* No more error records. */
		if (!estatus->block_status)
			return;

		if (cper_estatus_check(estatus)) {
			pr_err(FW_BUG "Invalid error record.\n");
			return;
		}

		pr_info_once("Error records from previous boot:\n");
		if (region_len < ACPI_BERT_PRINT_MAX_LEN)
			cper_estatus_print(KERN_INFO HW_ERR, estatus);
		else
			pr_info_once("Max print length exceeded, table data is available at:\n"
				     "/sys/firmware/acpi/tables/data/BERT");

		/*
		 * Because the boot error source is "one-time polled" type,
		 * clear Block Status of current Generic Error Status Block,
		 * once it's printed.
		 */
		estatus->block_status = 0;

		estatus = (void *)estatus + estatus_len;
		remain -= estatus_len;
	}
}

static int __init setup_bert_disable(char *str)
{
	bert_disable = 1;

	return 1;
}
__setup("bert_disable", setup_bert_disable);

static int __init bert_check_table(struct acpi_table_bert *bert_tab)
{
	if (bert_tab->header.length < sizeof(struct acpi_table_bert) ||
	    bert_tab->region_length < sizeof(struct acpi_bert_region))
		return -EINVAL;

	return 0;
}

static int __init bert_init(void)
{
	struct apei_resources bert_resources;
	struct acpi_bert_region *boot_error_region;
	struct acpi_table_bert *bert_tab;
	unsigned int region_len;
	acpi_status status;
	int rc = 0;

	if (acpi_disabled)
		return 0;

	if (bert_disable) {
		pr_info("Boot Error Record Table support is disabled.\n");
		return 0;
	}

	status = acpi_get_table(ACPI_SIG_BERT, 0, (struct acpi_table_header **)&bert_tab);
	if (status == AE_NOT_FOUND)
		return 0;

	if (ACPI_FAILURE(status)) {
		pr_err("get table failed, %s.\n", acpi_format_exception(status));
		return -EINVAL;
	}

	rc = bert_check_table(bert_tab);
	if (rc) {
		pr_err(FW_BUG "table invalid.\n");
		goto out_put_bert_tab;
	}

	region_len = bert_tab->region_length;
	apei_resources_init(&bert_resources);
	rc = apei_resources_add(&bert_resources, bert_tab->address,
				region_len, true);
	if (rc)
		goto out_put_bert_tab;
	rc = apei_resources_request(&bert_resources, "APEI BERT");
	if (rc)
		goto out_fini;
	boot_error_region = ioremap_cache(bert_tab->address, region_len);
	if (boot_error_region) {
		bert_print_all(boot_error_region, region_len);
		iounmap(boot_error_region);
	} else {
		rc = -ENOMEM;
	}

	apei_resources_release(&bert_resources);
out_fini:
	apei_resources_fini(&bert_resources);
out_put_bert_tab:
	acpi_put_table((struct acpi_table_header *)bert_tab);

	return rc;
}

late_initcall(bert_init);
