/*
 * Copyright (c) 2020 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdlib.h>
#include <device.h>
#include <shell/shell.h>

#include <drivers/edac.h>
#include "ibecc.h"

#define DEVICE_NAME DT_LABEL(DT_NODELABEL(ibecc))

/**
 * EDAC Error Injection interface
 *
 * edac inject addr [value]               Physical memory address base
 * edac inject mask [value]               Physical memory address mask
 * edac inject error_type                 Show / Set EDAC error type
 * edac inject trigger                    Trigger injection
 *
 * edac inject test_default               Set default injection parameters
 *
 * edac disable_nmi                       Experimental disable NMI
 * edac enable_nmi                        Experimental enable NMI
 *
 * EDAC Report interface
 *
 * edac info                              Show EDAC ECC / Parity error info
 * edac info ecc_error [show|clear]       Show ECC Errors
 * edac info parity_error [show|clear]    Show Parity Errors
 *
 * Physical memory access interface
 *
 * edac mem address [width [value]]       Physical memory read / write
 */

static void decode_ecc_error(const struct shell *shell, uint64_t ecc_error)
{
	uint64_t erradd = ECC_ERROR_ERRADD(ecc_error);
	unsigned long errsynd = ECC_ERROR_ERRSYND(ecc_error);

	shell_fprintf(shell, SHELL_NORMAL,
		      "CMI Error address: 0x%llx\n", erradd);
	shell_fprintf(shell, SHELL_NORMAL,
		      "Error Syndrome: 0x%lx\n", errsynd);

	if (ecc_error & ECC_ERROR_MERRSTS) {
		shell_fprintf(shell, SHELL_NORMAL,
			      "Uncorrectable Error (UE)\n");
	}

	if (ecc_error & ECC_ERROR_CERRSTS) {
		shell_fprintf(shell, SHELL_NORMAL,
			      "Correctable Error (CE)\n");
	}
}

static int cmd_edac_info(const struct shell *shell, size_t argc, char **argv)
{
	const struct device *dev;
	uint64_t error;
	int err;

	dev = device_get_binding(DEVICE_NAME);
	if (dev == NULL) {
		shell_error(shell, "IBECC device not found");
		return -ENODEV;
	}

	shell_fprintf(shell, SHELL_NORMAL, "Show EDAC status\n");

	err = edac_ecc_error_log_get(dev, &error);
	if (err != 0) {
		shell_error(shell, "Error getting ecc error log (err %d)",
			    err);
		return err;
	}

	shell_fprintf(shell, SHELL_NORMAL, "ECC Error Log 0x%llx\n", error);

	if (error != 0) {
		decode_ecc_error(shell, error);
	}

	err = edac_parity_error_log_get(dev, &error);
	if (err != 0) {
		shell_error(shell, "Error getting parity error log (err %d)",
			    err);
		return err;
	}

	shell_fprintf(shell, SHELL_NORMAL, "Parity Error Log 0x%llx\n", error);

	shell_fprintf(shell, SHELL_NORMAL,
		      "Errors correctable: %d Errors uncorrectable %d\n",
		      edac_errors_cor_get(dev), edac_errors_uc_get(dev));

	return err;
}

#if defined(CONFIG_EDAC_ERROR_INJECT)
static int cmd_inject_addr(const struct shell *shell, size_t argc, char **argv)
{
	const struct device *dev;
	int err;

	dev = device_get_binding(DEVICE_NAME);
	if (dev == NULL) {
		shell_error(shell, "IBECC device not found");
		return -ENODEV;
	}

	if (argc > 2) {
		/* Usage */
		shell_fprintf(shell, SHELL_NORMAL,
			      "Usage: edac inject %s [addr]\n", argv[0]);
		return -ENOTSUP;
	}

	if (argc == 1) {
		uint64_t addr;

		err = edac_inject_get_param1(dev, &addr);
		if (err != 0) {
			shell_error(shell, "Error getting address (err %d)",
				    err);
			return err;
		}

		shell_fprintf(shell, SHELL_NORMAL,
			      "Injection address base: 0x%lx\n", addr);
	} else {
		unsigned long value = strtoul(argv[1], NULL, 16);

		shell_fprintf(shell, SHELL_NORMAL,
			      "Set injection address base to: %s\n", argv[1]);

		err = edac_inject_set_param1(dev, value);
		if (err != 0) {
			shell_error(shell, "Error setting address (err %d)",
				    err);
			return err;
		}
	}

	return err;
}

static int cmd_inject_mask(const struct shell *shell, size_t argc, char **argv)
{
	const struct device *dev;
	int err;

	dev = device_get_binding(DEVICE_NAME);
	if (dev == NULL) {
		shell_error(shell, "IBECC device not found");
		return -ENODEV;
	}

	if (argc > 2) {
		/* Usage */
		shell_fprintf(shell, SHELL_NORMAL,
			      "Usage: edac inject %s [mask]\n", argv[0]);
		return -ENOTSUP;
	}

	if (argc == 1) {
		uint64_t mask;

		err = edac_inject_get_param2(dev, &mask);
		if (err != 0) {
			shell_error(shell, "Error getting mask (err %d)", err);
			return err;
		}

		shell_fprintf(shell, SHELL_NORMAL,
			      "Injection address mask: 0x%lx\n", mask);
	} else {
		uint64_t value = strtoul(argv[1], NULL, 16);

		shell_fprintf(shell, SHELL_NORMAL,
			      "Set injection address mask to %lx\n", value);

		err = edac_inject_set_param2(dev, value);
		if (err != 0) {
			shell_error(shell, "Error setting mask (err %d)", err);
			return err;
		}
	}

	return err;
}

static int cmd_inject_trigger(const struct shell *shell, size_t argc,
			      char **argv)
{
	const struct device *dev;

	dev = device_get_binding(DEVICE_NAME);
	if (dev == NULL) {
		shell_error(shell, "IBECC device not found");
		return -ENODEV;
	}

	shell_fprintf(shell, SHELL_NORMAL, "Triggering injection\n");

	edac_inject_error_trigger(dev);

	return 0;
}

static int cmd_inject_disable_nmi(const struct shell *shell, size_t argc,
				  char **argv)
{
	sys_out8((sys_in8(0x70) | 0x80), 0x70);

	return 0;
}

static int cmd_inject_enable_nmi(const struct shell *shell, size_t argc,
				 char **argv)
{
	sys_out8((sys_in8(0x70) & 0x7F), 0x70);

	return 0;
}

static const char *get_error_type(uint32_t type)
{
	switch (type) {
	case EDAC_ERROR_TYPE_DRAM_COR:
		return "correctable";
	case EDAC_ERROR_TYPE_DRAM_UC:
		return "uncorrectable";
	default:
		return "unknown";
	}
}

static int cmd_inject_error_type_show(const struct shell *shell, size_t argc,
				      char **argv)
{
	const struct device *dev;
	uint32_t error_type;
	int err;

	dev = device_get_binding(DEVICE_NAME);
	if (dev == NULL) {
		shell_error(shell, "IBECC device not found");
		return -ENODEV;
	}

	err = edac_inject_get_error_type(dev, &error_type);
	if (err != 0) {
		shell_error(shell, "Error getting error type (err %d)", err);
		return err;
	}

	shell_fprintf(shell, SHELL_NORMAL, "Injection error type: %s\n",
		      get_error_type(error_type));

	return err;
}

static int set_error_type(const struct shell *shell, uint32_t error_type)
{
	const struct device *dev;

	dev = device_get_binding(DEVICE_NAME);
	if (dev == NULL) {
		shell_error(shell, "IBECC device not found");
		return -ENODEV;
	}

	shell_fprintf(shell, SHELL_NORMAL, "Set injection error type: %s\n",
		      get_error_type(error_type));

	return edac_inject_set_error_type(dev, error_type);
}

static int cmd_inject_error_type_cor(const struct shell *shell, size_t argc,
				     char **argv)
{
	return set_error_type(shell, EDAC_ERROR_TYPE_DRAM_COR);
}

static int cmd_inject_error_type_uc(const struct shell *shell, size_t argc,
				    char **argv)
{
	return set_error_type(shell, EDAC_ERROR_TYPE_DRAM_UC);
}

static int cmd_inject_test(const struct shell *shell, size_t argc, char **argv)
{
	const struct device *dev;

	dev = device_get_binding(DEVICE_NAME);
	if (dev == NULL) {
		shell_error(shell, "IBECC device not found");
		return -ENODEV;
	}
	edac_inject_set_param1(dev, 0x1000);
	edac_inject_set_param2(dev, INJ_ADDR_BASE_MASK_MASK);
	edac_inject_set_error_type(dev, EDAC_ERROR_TYPE_DRAM_COR);
	edac_inject_error_trigger(dev);

	return 0;
}

SHELL_STATIC_SUBCMD_SET_CREATE(sub_inject_error_type_cmds,
	SHELL_CMD(correctable, NULL, "Set correctable error type",
		  cmd_inject_error_type_cor),
	SHELL_CMD(uncorrectable, NULL, "Set uncorrectable error type",
		  cmd_inject_error_type_uc),
	SHELL_SUBCMD_SET_END /* Array terminated */
);

/* EDAC Error Injection shell commands */
SHELL_STATIC_SUBCMD_SET_CREATE(sub_inject_cmds,
	SHELL_CMD(addr, NULL, "Get / Set physical address", cmd_inject_addr),
	SHELL_CMD(mask, NULL, "Get / Set address mask", cmd_inject_mask),
	SHELL_CMD_ARG(trigger, NULL, "Trigger injection", cmd_inject_trigger,
		      1, 0),
	SHELL_CMD(error_type, &sub_inject_error_type_cmds,
		  "Get / Set injection error type",
		  cmd_inject_error_type_show),
	SHELL_CMD(disable_nmi, NULL, "Disable NMI", cmd_inject_disable_nmi),
	SHELL_CMD(enable_nmi, NULL, "Enable NMI", cmd_inject_enable_nmi),
	SHELL_CMD_ARG(test_default, NULL, "Test default injection parameters",
		      cmd_inject_test, 1, 0),
	SHELL_SUBCMD_SET_END /* Array terminated */
);
#endif /* CONFIG_EDAC_ERROR_INJECT */

static int cmd_ecc_error_show(const struct shell *shell, size_t argc,
			      char **argv)
{
	const struct device *dev;
	uint64_t error;
	int err;

	dev = device_get_binding(DEVICE_NAME);
	if (dev == NULL) {
		shell_error(shell, "IBECC device not found");
		return -ENODEV;
	}

	err = edac_ecc_error_log_get(dev, &error);
	if (err != 0) {
		shell_error(shell, "Error getting error log (err %d)", err);
		return err;
	}

	shell_fprintf(shell, SHELL_NORMAL, "ECC Error: 0x%lx\n", error);

	if (error != 0) {
		decode_ecc_error(shell, error);
	}

	return err;
}

static int cmd_ecc_error_clear(const struct shell *shell, size_t argc,
			       char **argv)
{
	const struct device *dev;
	int err;

	dev = device_get_binding(DEVICE_NAME);
	if (dev == NULL) {
		shell_error(shell, "IBECC device not found");
		return -ENODEV;
	}

	err = edac_ecc_error_log_clear(dev);
	if (err != 0) {
		shell_error(shell, "Error clear ecc error log (err %d)",
			    err);
		return err;
	}

	shell_fprintf(shell, SHELL_NORMAL, "ECC Error Log cleared\n");

	return 0;
}

SHELL_STATIC_SUBCMD_SET_CREATE(sub_ecc_error_cmds,
	SHELL_CMD(show, NULL, "Show ECC errors", cmd_ecc_error_show),
	SHELL_CMD(clear, NULL, "Clear ECC errors", cmd_ecc_error_clear),
	SHELL_SUBCMD_SET_END /* Array terminated */
);

static int cmd_parity_error_show(const struct shell *shell, size_t argc,
				 char **argv)
{
	const struct device *dev;
	uint64_t error;
	int err;

	dev = device_get_binding(DEVICE_NAME);
	if (dev == NULL) {
		shell_error(shell, "IBECC device not found");
		return -ENODEV;
	}

	err = edac_parity_error_log_get(dev, &error);
	if (err != 0) {
		shell_error(shell, "Error getting parity error log (err %d)",
			    err);
		return err;
	}

	shell_fprintf(shell, SHELL_NORMAL, "Parity Error: 0x%lx\n", error);

	return 0;
}

static int cmd_parity_error_clear(const struct shell *shell, size_t argc,
				  char **argv)
{
	const struct device *dev;
	int err;

	dev = device_get_binding(DEVICE_NAME);
	if (dev == NULL) {
		shell_error(shell, "IBECC device not found");
		return -ENODEV;
	}

	err = edac_parity_error_log_clear(dev);
	if (err != 0) {
		shell_error(shell, "Error clear parity error log (err %d)",
			    err);
		return err;
	}

	shell_fprintf(shell, SHELL_NORMAL, "Parity Error Log cleared\n");

	return 0;
}

SHELL_STATIC_SUBCMD_SET_CREATE(sub_parity_error_cmds,
	SHELL_CMD(show, NULL, "Show Parity errors", cmd_parity_error_show),
	SHELL_CMD(clear, NULL, "Clear Parity errors", cmd_parity_error_clear),
	SHELL_SUBCMD_SET_END /* Array terminated */
);

/* EDAC Info shell commands */
SHELL_STATIC_SUBCMD_SET_CREATE(sub_info_cmds,
	SHELL_CMD(ecc_error, &sub_ecc_error_cmds,
		  "ECC Error Show / Clear commands", cmd_ecc_error_show),
	SHELL_CMD(parity_error, &sub_parity_error_cmds,
		  "Parity Error Show / Clear commands", cmd_parity_error_show),
	SHELL_SUBCMD_SET_END /* Array terminated */
);

SHELL_STATIC_SUBCMD_SET_CREATE(sub_edac_cmds,
	SHELL_CMD(info, &sub_info_cmds,
		  "Show EDAC information\n"
		  "edac info <subcommands>", cmd_edac_info),
#if defined(CONFIG_EDAC_ERROR_INJECT)
	/* This does not work with SHELL_COND_CMD */
	SHELL_CMD(inject, &sub_inject_cmds,
		  "Inject ECC error commands\n"
		  "edac inject <subcommands>", NULL),
#endif
	SHELL_SUBCMD_SET_END /* Array terminated. */
);

SHELL_CMD_REGISTER(edac, &sub_edac_cmds, "EDAC information", cmd_edac_info);
