// SPDX-License-Identifier: GPL-2.0
/*
 * UEFI Common Platform Error Record (CPER) support
 *
 * Copyright (C) 2017, The Linux Foundation. All rights reserved.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/time.h>
#include <linux/cper.h>
#include <linux/dmi.h>
#include <linux/acpi.h>
#include <linux/pci.h>
#include <linux/printk.h>
#include <linux/bcd.h>
#include <acpi/ghes.h>
#include <ras/ras_event.h>

static const char * const arm_reg_ctx_strs[] = {
	"AArch32 general purpose registers",
	"AArch32 EL1 context registers",
	"AArch32 EL2 context registers",
	"AArch32 secure context registers",
	"AArch64 general purpose registers",
	"AArch64 EL1 context registers",
	"AArch64 EL2 context registers",
	"AArch64 EL3 context registers",
	"Misc. system register structure",
};

static const char * const arm_err_trans_type_strs[] = {
	"Instruction",
	"Data Access",
	"Generic",
};

static const char * const arm_bus_err_op_strs[] = {
	"Generic error (type cannot be determined)",
	"Generic read (type of instruction or data request cannot be determined)",
	"Generic write (type of instruction of data request cannot be determined)",
	"Data read",
	"Data write",
	"Instruction fetch",
	"Prefetch",
};

static const char * const arm_cache_err_op_strs[] = {
	"Generic error (type cannot be determined)",
	"Generic read (type of instruction or data request cannot be determined)",
	"Generic write (type of instruction of data request cannot be determined)",
	"Data read",
	"Data write",
	"Instruction fetch",
	"Prefetch",
	"Eviction",
	"Snooping (processor initiated a cache snoop that resulted in an error)",
	"Snooped (processor raised a cache error caused by another processor or device snooping its cache)",
	"Management",
};

static const char * const arm_tlb_err_op_strs[] = {
	"Generic error (type cannot be determined)",
	"Generic read (type of instruction or data request cannot be determined)",
	"Generic write (type of instruction of data request cannot be determined)",
	"Data read",
	"Data write",
	"Instruction fetch",
	"Prefetch",
	"Local management operation (processor initiated a TLB management operation that resulted in an error)",
	"External management operation (processor raised a TLB error caused by another processor or device broadcasting TLB operations)",
};

static const char * const arm_bus_err_part_type_strs[] = {
	"Local processor originated request",
	"Local processor responded to request",
	"Local processor observed",
	"Generic",
};

static const char * const arm_bus_err_addr_space_strs[] = {
	"External Memory Access",
	"Internal Memory Access",
	"Unknown",
	"Device Memory Access",
};

static void cper_print_arm_err_info(const char *pfx, u32 type,
				    u64 error_info)
{
	u8 trans_type, op_type, level, participation_type, address_space;
	u16 mem_attributes;
	bool proc_context_corrupt, corrected, precise_pc, restartable_pc;
	bool time_out, access_mode;

	/*
	 * Vendor type errors have error information values that are vendor
	 * specific.
	 */
	if (type & CPER_ARM_VENDOR_ERROR)
		return;

	if (error_info & CPER_ARM_ERR_VALID_TRANSACTION_TYPE) {
		trans_type = ((error_info >> CPER_ARM_ERR_TRANSACTION_SHIFT)
			      & CPER_ARM_ERR_TRANSACTION_MASK);
		if (trans_type < ARRAY_SIZE(arm_err_trans_type_strs)) {
			printk("%stransaction type: %s\n", pfx,
			       arm_err_trans_type_strs[trans_type]);
		}
	}

	if (error_info & CPER_ARM_ERR_VALID_OPERATION_TYPE) {
		op_type = ((error_info >> CPER_ARM_ERR_OPERATION_SHIFT)
			   & CPER_ARM_ERR_OPERATION_MASK);
		if (type & CPER_ARM_CACHE_ERROR) {
			if (op_type < ARRAY_SIZE(arm_cache_err_op_strs)) {
				printk("%scache error, operation type: %s\n", pfx,
				       arm_cache_err_op_strs[op_type]);
			}
		}
		if (type & CPER_ARM_TLB_ERROR) {
			if (op_type < ARRAY_SIZE(arm_tlb_err_op_strs)) {
				printk("%sTLB error, operation type: %s\n", pfx,
				       arm_tlb_err_op_strs[op_type]);
			}
		}
		if (type & CPER_ARM_BUS_ERROR) {
			if (op_type < ARRAY_SIZE(arm_bus_err_op_strs)) {
				printk("%sbus error, operation type: %s\n", pfx,
				       arm_bus_err_op_strs[op_type]);
			}
		}
	}

	if (error_info & CPER_ARM_ERR_VALID_LEVEL) {
		level = ((error_info >> CPER_ARM_ERR_LEVEL_SHIFT)
			 & CPER_ARM_ERR_LEVEL_MASK);
		if (type & CPER_ARM_CACHE_ERROR)
			printk("%scache level: %d\n", pfx, level);

		if (type & CPER_ARM_TLB_ERROR)
			printk("%sTLB level: %d\n", pfx, level);

		if (type & CPER_ARM_BUS_ERROR)
			printk("%saffinity level at which the bus error occurred: %d\n",
			       pfx, level);
	}

	if (error_info & CPER_ARM_ERR_VALID_PROC_CONTEXT_CORRUPT) {
		proc_context_corrupt = ((error_info >> CPER_ARM_ERR_PC_CORRUPT_SHIFT)
					& CPER_ARM_ERR_PC_CORRUPT_MASK);
		if (proc_context_corrupt)
			printk("%sprocessor context corrupted\n", pfx);
		else
			printk("%sprocessor context not corrupted\n", pfx);
	}

	if (error_info & CPER_ARM_ERR_VALID_CORRECTED) {
		corrected = ((error_info >> CPER_ARM_ERR_CORRECTED_SHIFT)
			     & CPER_ARM_ERR_CORRECTED_MASK);
		if (corrected)
			printk("%sthe error has been corrected\n", pfx);
		else
			printk("%sthe error has not been corrected\n", pfx);
	}

	if (error_info & CPER_ARM_ERR_VALID_PRECISE_PC) {
		precise_pc = ((error_info >> CPER_ARM_ERR_PRECISE_PC_SHIFT)
			      & CPER_ARM_ERR_PRECISE_PC_MASK);
		if (precise_pc)
			printk("%sPC is precise\n", pfx);
		else
			printk("%sPC is imprecise\n", pfx);
	}

	if (error_info & CPER_ARM_ERR_VALID_RESTARTABLE_PC) {
		restartable_pc = ((error_info >> CPER_ARM_ERR_RESTARTABLE_PC_SHIFT)
				  & CPER_ARM_ERR_RESTARTABLE_PC_MASK);
		if (restartable_pc)
			printk("%sProgram execution can be restarted reliably at the PC associated with the error.\n", pfx);
	}

	/* The rest of the fields are specific to bus errors */
	if (type != CPER_ARM_BUS_ERROR)
		return;

	if (error_info & CPER_ARM_ERR_VALID_PARTICIPATION_TYPE) {
		participation_type = ((error_info >> CPER_ARM_ERR_PARTICIPATION_TYPE_SHIFT)
				      & CPER_ARM_ERR_PARTICIPATION_TYPE_MASK);
		if (participation_type < ARRAY_SIZE(arm_bus_err_part_type_strs)) {
			printk("%sparticipation type: %s\n", pfx,
			       arm_bus_err_part_type_strs[participation_type]);
		}
	}

	if (error_info & CPER_ARM_ERR_VALID_TIME_OUT) {
		time_out = ((error_info >> CPER_ARM_ERR_TIME_OUT_SHIFT)
			    & CPER_ARM_ERR_TIME_OUT_MASK);
		if (time_out)
			printk("%srequest timed out\n", pfx);
	}

	if (error_info & CPER_ARM_ERR_VALID_ADDRESS_SPACE) {
		address_space = ((error_info >> CPER_ARM_ERR_ADDRESS_SPACE_SHIFT)
				 & CPER_ARM_ERR_ADDRESS_SPACE_MASK);
		if (address_space < ARRAY_SIZE(arm_bus_err_addr_space_strs)) {
			printk("%saddress space: %s\n", pfx,
			       arm_bus_err_addr_space_strs[address_space]);
		}
	}

	if (error_info & CPER_ARM_ERR_VALID_MEM_ATTRIBUTES) {
		mem_attributes = ((error_info >> CPER_ARM_ERR_MEM_ATTRIBUTES_SHIFT)
				  & CPER_ARM_ERR_MEM_ATTRIBUTES_MASK);
		printk("%smemory access attributes:0x%x\n", pfx, mem_attributes);
	}

	if (error_info & CPER_ARM_ERR_VALID_ACCESS_MODE) {
		access_mode = ((error_info >> CPER_ARM_ERR_ACCESS_MODE_SHIFT)
			       & CPER_ARM_ERR_ACCESS_MODE_MASK);
		if (access_mode)
			printk("%saccess mode: normal\n", pfx);
		else
			printk("%saccess mode: secure\n", pfx);
	}
}

void cper_print_proc_arm(const char *pfx,
			 const struct cper_sec_proc_arm *proc,
			 u32 length)
{
	int i, len, max_ctx_type;
	struct cper_arm_err_info *err_info;
	struct cper_arm_ctx_info *ctx_info;
	char newpfx[64], infopfx[ARRAY_SIZE(newpfx) + 1];
	char error_type[120];

	printk("%sMIDR: 0x%016llx\n", pfx, proc->midr);

	len = proc->section_length - (sizeof(*proc) +
		proc->err_info_num * (sizeof(*err_info)));

	if (len < 0 || proc->section_length > length) {
		printk("%ssection length: %d, CPER size: %d\n",
		       pfx, proc->section_length, length);
		printk("%ssection length is too %s\n", pfx,
		       (len < 0) ? "small" : "big");
		printk("%sfirmware-generated error record is incorrect\n", pfx);
		printk("%sERR_INFO_NUM is %d\n", pfx, proc->err_info_num);
		return;
	}

	if (proc->validation_bits & CPER_ARM_VALID_MPIDR)
		printk("%sMultiprocessor Affinity Register (MPIDR): 0x%016llx\n",
			pfx, proc->mpidr);

	if (proc->validation_bits & CPER_ARM_VALID_AFFINITY_LEVEL)
		printk("%serror affinity level: %d\n", pfx,
			proc->affinity_level);

	if (proc->validation_bits & CPER_ARM_VALID_RUNNING_STATE) {
		printk("%srunning state: 0x%x\n", pfx, proc->running_state);
		printk("%sPower State Coordination Interface state: %d\n",
			pfx, proc->psci_state);
	}

	snprintf(newpfx, sizeof(newpfx), "%s ", pfx);

	err_info = (struct cper_arm_err_info *)(proc + 1);
	for (i = 0; i < proc->err_info_num; i++) {
		printk("%sError info structure %d:\n", pfx, i);

		printk("%snum errors: %d\n", pfx, err_info->multiple_error + 1);

		if (err_info->validation_bits & CPER_ARM_INFO_VALID_FLAGS) {
			if (err_info->flags & CPER_ARM_INFO_FLAGS_FIRST)
				printk("%sfirst error captured\n", newpfx);
			if (err_info->flags & CPER_ARM_INFO_FLAGS_LAST)
				printk("%slast error captured\n", newpfx);
			if (err_info->flags & CPER_ARM_INFO_FLAGS_PROPAGATED)
				printk("%spropagated error captured\n",
				       newpfx);
			if (err_info->flags & CPER_ARM_INFO_FLAGS_OVERFLOW)
				printk("%soverflow occurred, error info is incomplete\n",
				       newpfx);
		}

		cper_bits_to_str(error_type, sizeof(error_type),
				 FIELD_GET(CPER_ARM_ERR_TYPE_MASK, err_info->type),
				 cper_proc_error_type_strs,
				 ARRAY_SIZE(cper_proc_error_type_strs));

		printk("%serror_type: 0x%02x: %s%s\n", newpfx, err_info->type,
		       error_type,
		       (err_info->type & ~CPER_ARM_ERR_TYPE_MASK) ? " with reserved bit(s)" : "");

		if (err_info->validation_bits & CPER_ARM_INFO_VALID_ERR_INFO) {
			printk("%serror_info: 0x%016llx\n", newpfx,
			       err_info->error_info);
			snprintf(infopfx, sizeof(infopfx), "%s ", newpfx);
			cper_print_arm_err_info(infopfx, err_info->type,
						err_info->error_info);
		}
		if (err_info->validation_bits & CPER_ARM_INFO_VALID_VIRT_ADDR)
			printk("%svirtual fault address: 0x%016llx\n",
				newpfx, err_info->virt_fault_addr);
		if (err_info->validation_bits & CPER_ARM_INFO_VALID_PHYSICAL_ADDR)
			printk("%sphysical fault address: 0x%016llx\n",
				newpfx, err_info->physical_fault_addr);
		err_info += 1;
	}

	ctx_info = (struct cper_arm_ctx_info *)err_info;
	max_ctx_type = ARRAY_SIZE(arm_reg_ctx_strs) - 1;
	for (i = 0; i < proc->context_info_num; i++) {
		int size = ALIGN(sizeof(*ctx_info) + ctx_info->size, 16);

		printk("%sContext info structure %d:\n", pfx, i);
		if (len < size) {
			printk("%ssection length is too small\n", newpfx);
			printk("%sfirmware-generated error record is incorrect\n", pfx);
			return;
		}
		if (ctx_info->type > max_ctx_type) {
			printk("%sInvalid context type: %d (max: %d)\n",
				newpfx, ctx_info->type, max_ctx_type);
			return;
		}
		printk("%sregister context type: %s\n", newpfx,
			arm_reg_ctx_strs[ctx_info->type]);
		print_hex_dump(newpfx, "", DUMP_PREFIX_OFFSET, 16, 4,
				(ctx_info + 1), ctx_info->size, 0);
		len -= size;
		ctx_info = (struct cper_arm_ctx_info *)((long)ctx_info + size);
	}

	if (len > 0) {
		printk("%sVendor specific error info has %u bytes:\n", pfx,
		       len);
		print_hex_dump(newpfx, "", DUMP_PREFIX_OFFSET, 16, 4, ctx_info,
				len, true);
	}
}
