/* Copyright 2013-2014 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define pr_fmt(fmt) "FSPMEMERR: " fmt
#include <skiboot.h>
#include <opal.h>
#include <opal-msg.h>
#include <lock.h>
#include <fsp.h>
#include <errorlog.h>

/* FSP sends real address of 4K memory page. */
#define MEM_ERR_PAGE_SIZE_4K	(1UL << 12)

/* maximum number of error event to hold until linux consumes it. */
#define MERR_MAX_RECORD		1024

struct fsp_mem_err_node {
	struct list_node list;
	struct OpalMemoryErrorData data;
};

static LIST_HEAD(merr_free_list);
static LIST_HEAD(mem_error_list);
/*
 * lock is used to protect overwriting of merr_free_list and mem_error_list
 * list.
 */
static struct lock mem_err_lock = LOCK_UNLOCKED;

DEFINE_LOG_ENTRY(OPAL_RC_MEM_ERR_RES, OPAL_PLATFORM_ERR_EVT, OPAL_MEM_ERR,
			OPAL_MISC_SUBSYSTEM, OPAL_PREDICTIVE_ERR_GENERAL,
			OPAL_NA);

DEFINE_LOG_ENTRY(OPAL_RC_MEM_ERR_DEALLOC, OPAL_PLATFORM_ERR_EVT, OPAL_MEM_ERR,
			OPAL_MISC_SUBSYSTEM, OPAL_PREDICTIVE_ERR_GENERAL,
			OPAL_NA);

static bool send_response_to_fsp(u32 cmd_sub_mod)
{
	struct fsp_msg *rsp;
	int rc = -ENOMEM;

	rsp = fsp_mkmsg(cmd_sub_mod, 0);
	if (rsp)
		rc = fsp_queue_msg(rsp, fsp_freemsg);
	if (rc) {
		fsp_freemsg(rsp);
		/* XXX Generate error logs */
		prerror("Error %d queueing FSP memory error reply\n", rc);
		return false;
	}
	return true;
}

/*
 * Queue up the memory error message for delivery.
 *
 * queue_event_for_delivery get called from two places.
 * 1) from queue_mem_err_node when new fsp mem error is available and
 * 2) from completion callback indicating that linux has consumed an message.
 *
 * TODO:
 * There is a chance that, we may not get a free slot to queue our event
 * for delivery to linux during both the above invocations. In that case
 * we end up holding events with us until next fsp memory error comes in.
 * We need to address this case either here OR fix up messaging infrastructure
 * to make sure at least one slot will always be available per message type.
 *
 * XXX: BenH: I changed the msg infrastructure to attempt an allocation
 *            in that case, at least until we clarify a bit better how
 *            we want to handle things.
 */
static void queue_event_for_delivery(void *data __unused)
{
	struct fsp_mem_err_node *entry;
	uint64_t *merr_data;
	int rc;

	lock(&mem_err_lock);
	entry = list_pop(&mem_error_list, struct fsp_mem_err_node, list);
	unlock(&mem_err_lock);

	if (!entry)
		return;

	/*
	 * struct OpalMemoryErrorData is of (4 * 64 bits) size and well packed
	 * structure. Hence use uint64_t pointer to pass entire structure
	 * using 4 params in generic message format.
	 */
	merr_data = (uint64_t *)&entry->data;

	/* queue up for delivery */
	rc = opal_queue_msg(OPAL_MSG_MEM_ERR, NULL,
			    queue_event_for_delivery,
			    merr_data[0], merr_data[1],
			    merr_data[2], merr_data[3]);
	lock(&mem_err_lock);
	if (rc) {
		/*
		 * Failed to queue up the event for delivery. No free slot
		 * available. There is a chance that we are trying to queue
		 * up multiple event at the same time. We may already have
		 * at least one event queued up, in that case we will be
		 * called again through completion callback and we should
		 * be able to grab empty slot then.
		 *
		 * For now, put this node back on mem_error_list.
		 */
		list_add(&mem_error_list, &entry->list);
	} else
		list_add(&merr_free_list, &entry->list);
	unlock(&mem_err_lock);
}

static int queue_mem_err_node(struct OpalMemoryErrorData *merr_evt)
{
	struct fsp_mem_err_node *entry;

	lock(&mem_err_lock);
	entry = list_pop(&merr_free_list, struct fsp_mem_err_node, list);
	if (!entry) {
		printf("Failed to queue up memory error event.\n");
		unlock(&mem_err_lock);
		return -ENOMEM;
	}

	entry->data = *merr_evt;
	list_add(&mem_error_list, &entry->list);
	unlock(&mem_err_lock);

	/* Queue up the event for delivery to OS. */
	queue_event_for_delivery(NULL);
	return 0;
}

/* Check if memory resilience event for same address already exists. */
static bool is_resilience_event_exist(u64 paddr)
{
	struct fsp_mem_err_node *entry;
	struct OpalMemoryErrorData *merr_evt;
	int found = 0;

	lock(&mem_err_lock);
	list_for_each(&mem_error_list, entry, list) {
		merr_evt = &entry->data;
		if ((merr_evt->type == OPAL_MEM_ERR_TYPE_RESILIENCE) &&
		    (be64_to_cpu(merr_evt->u.resilience.physical_address_start)
							    == paddr)) {
			found = 1;
			break;
		}
	}
	unlock(&mem_err_lock);
	return !!found;
}

/*
 * handle Memory Resilience error message.
 * Section 28.2 of Hypervisor to FSP Mailbox Interface Specification.
 *
 * The flow for Memory Resilence Event is:
 * 1. PRD component in FSP gets a recoverable attention from hardware when
 *    there is a corretable/uncorrectable memory error to free up a page.
 * 2. PRD sends Memory Resilence Command to hypervisor with the real address of
 *    the 4K memory page in which the error occurred.
 * 3. The hypervisor acknowledges with a status immediately. Immediate
 *    acknowledgment doesn’t require the freeing of the page to be completed.
 */
static bool handle_memory_resilience(u32 cmd_sub_mod, u64 paddr)
{
	int rc = 0;
	struct OpalMemoryErrorData mem_err_evt;
	struct errorlog *buf;

	memset(&mem_err_evt, 0, sizeof(struct OpalMemoryErrorData));
	/* Check arguments */
	if (paddr == 0) {
		prerror("memory resilience: Invalid real address.\n");
		return send_response_to_fsp(FSP_RSP_MEM_RES |
					    FSP_STATUS_GENERIC_ERROR);
	}

	/* Check if event already exist for same address. */
	if (is_resilience_event_exist(paddr))
		goto send_response;

	/* Populate an event. */
	mem_err_evt.version = OpalMemErr_V1;
	mem_err_evt.type = OPAL_MEM_ERR_TYPE_RESILIENCE;

	switch (cmd_sub_mod) {
	case FSP_CMD_MEM_RES_CE:
		/*
		 * Should we keep counter for corrected errors in
		 * sapphire OR let linux (PowerNV) handle it?
		 *
		 * For now, send corrected errors to linux and let
		 * linux handle corrected errors thresholding.
		 */
		mem_err_evt.flags |= cpu_to_be16(OPAL_MEM_CORRECTED_ERROR);
		mem_err_evt.u.resilience.resil_err_type =
					OPAL_MEM_RESILIENCE_CE;
		break;
	case FSP_CMD_MEM_RES_UE:
		mem_err_evt.u.resilience.resil_err_type =
					OPAL_MEM_RESILIENCE_UE;
		break;
	case FSP_CMD_MEM_RES_UE_SCRB:
		mem_err_evt.u.resilience.resil_err_type =
					OPAL_MEM_RESILIENCE_UE_SCRUB;
		break;
	}
	mem_err_evt.u.resilience.physical_address_start = cpu_to_be64(paddr);
	mem_err_evt.u.resilience.physical_address_end =
		cpu_to_be64(paddr + MEM_ERR_PAGE_SIZE_4K);

	/* Queue up the event and inform OS about it. */
	rc = queue_mem_err_node(&mem_err_evt);

send_response:
	/* Queue up an OK response to the resilience message itself */
	if (!rc)
		return send_response_to_fsp(FSP_RSP_MEM_RES);
	else {
		buf = opal_elog_create(&e_info(OPAL_RC_MEM_ERR_RES), 0);
		log_append_msg(buf,
			"OPAL_MEM_ERR: Cannot queue up memory "
			"resilience error event to the OS");
		log_add_section(buf, 0x44455350);
		log_append_data(buf, (char *) &mem_err_evt,
					   sizeof(struct OpalMemoryErrorData));
		log_commit(buf);
		return false;
	}
}

/* update existing event entry if match is found. */
static bool update_memory_deallocation_event(u64 paddr_start, u64 paddr_end)
{
	struct fsp_mem_err_node *entry;
	struct OpalMemoryErrorData *merr_evt;
	int found = 0;

	lock(&mem_err_lock);
	list_for_each(&mem_error_list, entry, list) {
		merr_evt = &entry->data;
		if ((merr_evt->type == OPAL_MEM_ERR_TYPE_DYN_DALLOC) &&
		    (be64_to_cpu(merr_evt->u.dyn_dealloc.physical_address_start)
							    == paddr_start)) {
			found = 1;
			if (be64_to_cpu(merr_evt->u.dyn_dealloc.physical_address_end)
								< paddr_end)
				merr_evt->u.dyn_dealloc.physical_address_end =
					cpu_to_be64(paddr_end);
			break;
		}
	}
	unlock(&mem_err_lock);
	return !!found;
}

/*
 * Handle dynamic memory deallocation message.
 *
 * When a condition occurs in which we need to do a large scale memory
 * deallocation, PRD will send a starting and ending address of an area of
 * memory to Hypervisor. Hypervisor then need to use this to deallocate all
 * pages between and including the addresses.
 *
 */
static bool handle_memory_deallocation(u64 paddr_start, u64 paddr_end)
{
	int rc = 0;
	u8 err = 0;
	struct OpalMemoryErrorData mem_err_evt;
	struct errorlog *buf;

	memset(&mem_err_evt, 0, sizeof(struct OpalMemoryErrorData));
	/* Check arguments */
	if ((paddr_start == 0) || (paddr_end == 0)) {
		prerror("memory deallocation: Invalid "
			"starting/ending real address.\n");
		err = FSP_STATUS_GENERIC_ERROR;
	}

	/* If we had an error, send response to fsp and return */
	if (err)
		return send_response_to_fsp(FSP_RSP_MEM_DYN_DEALLOC | err);

	/*
	 * FSP can send dynamic memory deallocation multiple times for the
	 * same address/address ranges. Hence check and update if we already
	 * have sam event queued.
	 */
	if (update_memory_deallocation_event(paddr_start, paddr_end))
		goto send_response;

	/* Populate an new event. */
	mem_err_evt.version = OpalMemErr_V1;
	mem_err_evt.type = OPAL_MEM_ERR_TYPE_DYN_DALLOC;
	mem_err_evt.u.dyn_dealloc.dyn_err_type =
					OPAL_MEM_DYNAMIC_DEALLOC;
	mem_err_evt.u.dyn_dealloc.physical_address_start = cpu_to_be64(paddr_start);
	mem_err_evt.u.dyn_dealloc.physical_address_end = cpu_to_be64(paddr_end);

	/* Queue up the event and inform OS about it. */
	rc = queue_mem_err_node(&mem_err_evt);

send_response:
	/* Queue up an OK response to the memory deallocation message itself */
	if (!rc)
		return send_response_to_fsp(FSP_RSP_MEM_DYN_DEALLOC);
	else {
		buf = opal_elog_create(&e_info(OPAL_RC_MEM_ERR_DEALLOC), 0);
		log_append_msg(buf,
			"OPAL_MEM_ERR: Cannot queue up memory "
			"deallocation error event to the OS");
		log_add_section(buf, 0x44455350);
		log_append_data(buf, (char *)&mem_err_evt,
					   sizeof(struct OpalMemoryErrorData));
		log_commit(buf);
		return false;
	}
}

/* Receive a memory error mesages and handle it. */
static bool fsp_mem_err_msg(u32 cmd_sub_mod, struct fsp_msg *msg)
{
	u64 paddr_start, paddr_end;

	printf("Received 0x%08ux command\n", cmd_sub_mod);
	switch (cmd_sub_mod) {
	case FSP_CMD_MEM_RES_CE:
	case FSP_CMD_MEM_RES_UE:
	case FSP_CMD_MEM_RES_UE_SCRB:
		/*
		 * We get the memory relilence command from FSP for
		 * correctable/Uncorrectable/scrub UE errors with real
		 * address of 4K memory page in which the error occurred.
		 */
		paddr_start = be64_to_cpu(*((__be64 *)&msg->data.words[0]));
		printf("Got memory resilience error message for "
		       "paddr=0x%016llux\n", paddr_start);
		return handle_memory_resilience(cmd_sub_mod, paddr_start);
	case FSP_CMD_MEM_DYN_DEALLOC:
		paddr_start = be64_to_cpu(*((__be64 *)&msg->data.words[0]));
		paddr_end = be64_to_cpu(*((__be64 *)&msg->data.words[2]));
		printf("Got dynamic memory deallocation message: "
		       "paddr_start=0x%016llux, paddr_end=0x%016llux\n",
		       paddr_start, paddr_end);
		return handle_memory_deallocation(paddr_start, paddr_end);
	}
	return false;
}

/*
 * pre allocate memory to hold maximum of 128 memory error event until linux
 * consumes it.
 */
static int init_merr_free_list(uint32_t num_entries)
{
	struct fsp_mem_err_node *entry;
	int i;

	entry = zalloc(sizeof(struct fsp_mem_err_node) * num_entries);
	if (!entry)
		return -ENOMEM;

	for (i = 0; i < num_entries; ++i, entry++)
		list_add_tail(&merr_free_list, &entry->list);

	return 0;
}

static struct fsp_client fsp_mem_err_client = {
	.message = fsp_mem_err_msg,
};

void fsp_memory_err_init(void)
{
	int rc;

	printf("Intializing fsp memory handling.\n");
	/* If we have an FSP, register for notifications */
	if (!fsp_present())
		return;

	/* pre allocate memory for 128 record */
	rc = init_merr_free_list(MERR_MAX_RECORD);
	if (rc < 0)
		return;

	fsp_register_client(&fsp_mem_err_client, FSP_MCLASS_MEMORY_ERR);
}
