// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2018 IBM Corp.

#define _GNU_SOURCE
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <poll.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/timerfd.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <inttypes.h>

#include "mbox.h"
#include "common.h"
#include "transport_mbox.h"
#include "windows.h"
#include "lpc.h"

struct errno_map {
	int rc;
	int mbox_errno;
};

static const struct errno_map errno_map_v1[] = {
	{ 0, MBOX_R_SUCCESS },
	{ EACCES, MBOX_R_PARAM_ERROR },
	{ EBADMSG, MBOX_R_PARAM_ERROR },
	{ EBUSY, MBOX_R_SYSTEM_ERROR },
	{ EINVAL, MBOX_R_PARAM_ERROR },
	{ ENOTSUP, MBOX_R_PARAM_ERROR },
	{ EPERM, MBOX_R_PARAM_ERROR },
	{ EPROTO, MBOX_R_PARAM_ERROR },
	{ ETIMEDOUT, MBOX_R_TIMEOUT },
	{ -1, MBOX_R_SYSTEM_ERROR },
};

static const struct errno_map errno_map_v2[] = {
	{ 0, MBOX_R_SUCCESS },
	{ EACCES, MBOX_R_WINDOW_ERROR },
	{ EBADMSG, MBOX_R_SEQ_ERROR },
	{ EBUSY, MBOX_R_BUSY },
	{ EINVAL, MBOX_R_PARAM_ERROR },
	{ ENOTSUP, MBOX_R_PARAM_ERROR },
	{ EPERM, MBOX_R_WINDOW_ERROR },
	{ EPROTO, MBOX_R_PARAM_ERROR },
	{ ETIMEDOUT, MBOX_R_TIMEOUT },
	{ -1, MBOX_R_SYSTEM_ERROR },
};

static const struct errno_map *errno_maps[] = {
	[0] = NULL,
	[1] = errno_map_v1,
	[2] = errno_map_v2,
};

static inline int mbox_xlate_errno(struct mbox_context *context,
					     int rc)
{
	const struct errno_map *entry;

	rc = -rc;
	MSG_DBG("Translating errno %d: %s\n", rc, strerror(rc));
	for(entry = errno_maps[context->version]; entry->rc != -1; entry++) {
		if (rc == entry->rc) {
			return entry->mbox_errno;
		}
	}

	return entry->mbox_errno;
}

/*
 * write_bmc_event_reg() - Write to the BMC controlled status register (reg 15)
 * @context:	The mbox context pointer
 *
 * Return:	0 on success otherwise negative error code
 */
static int write_bmc_event_reg(struct mbox_context *context)
{
	int rc;

	/* Seek mbox registers */
	rc = lseek(context->fds[MBOX_FD].fd, MBOX_BMC_EVENT, SEEK_SET);
	if (rc != MBOX_BMC_EVENT) {
		MSG_ERR("Couldn't lseek mbox to byte %d: %s\n", MBOX_BMC_EVENT,
				strerror(errno));
		return -MBOX_R_SYSTEM_ERROR;
	}

	/* Write to mbox status register */
	rc = write(context->fds[MBOX_FD].fd, &context->bmc_events, 1);
	if (rc != 1) {
		MSG_ERR("Couldn't write to BMC status reg: %s\n",
				strerror(errno));
		return -MBOX_R_SYSTEM_ERROR;
	}

	/* Reset to start */
	rc = lseek(context->fds[MBOX_FD].fd, 0, SEEK_SET);
	if (rc) {
		MSG_ERR("Couldn't reset MBOX offset to zero: %s\n",
				strerror(errno));
		return -MBOX_R_SYSTEM_ERROR;
	}

	return 0;
}

/*
 * set_bmc_events() - Set BMC events
 * @context:	The mbox context pointer
 * @bmc_event:	The bits to set
 * @write_back:	Whether to write back to the register -> will interrupt host
 *
 * Return:	0 on success otherwise negative error code
 */
int set_bmc_events(struct mbox_context *context, uint8_t bmc_event,
		   bool write_back)
{
	uint8_t mask = 0x00;

	switch (context->version) {
	case API_VERSION_1:
		mask = BMC_EVENT_V1_MASK;
		break;
	default:
		mask = BMC_EVENT_V2_MASK;
		break;
	}

	context->bmc_events |= (bmc_event & mask);
	MSG_DBG("BMC Events set to: 0x%.2x\n", context->bmc_events);

	return write_back ? write_bmc_event_reg(context) : 0;
}

/*
 * clr_bmc_events() - Clear BMC events
 * @context:	The mbox context pointer
 * @bmc_event:	The bits to clear
 * @write_back:	Whether to write back to the register -> will interrupt host
 *
 * Return:	0 on success otherwise negative error code
 */
int clr_bmc_events(struct mbox_context *context, uint8_t bmc_event,
		   bool write_back)
{
	context->bmc_events &= ~bmc_event;
	MSG_DBG("BMC Events clear to: 0x%.2x\n", context->bmc_events);

	return write_back ? write_bmc_event_reg(context) : 0;
}

/* Command Handlers */

/*
 * Command: RESET_STATE
 * Reset the LPC mapping to point back at the flash, or memory in case we're
 * using a virtual pnor.
 */
int mbox_handle_reset(struct mbox_context *context,
			     union mbox_regs *req, struct mbox_msg *resp)
{
	return context->protocol->reset(context);
}

/*
 * Command: GET_MBOX_INFO
 * Get the API version, default window size and block size
 * We also set the LPC mapping to point to the reserved memory region here so
 * this command must be called before any window manipulation
 *
 * V1:
 * ARGS[0]: API Version
 *
 * RESP[0]: API Version
 * RESP[1:2]: Default read window size (number of blocks)
 * RESP[3:4]: Default write window size (number of blocks)
 * RESP[5]: Block size (as shift)
 *
 * V2:
 * ARGS[0]: API Version
 *
 * RESP[0]: API Version
 * RESP[1:2]: Default read window size (number of blocks)
 * RESP[3:4]: Default write window size (number of blocks)
 * RESP[5]: Block size (as shift)
 */
int mbox_handle_mbox_info(struct mbox_context *context,
				 union mbox_regs *req, struct mbox_msg *resp)
{
	uint8_t mbox_api_version = req->msg.args[0];
	struct protocol_get_info io = {
		.req = { .api_version = mbox_api_version }
	};
	int rc;

	rc = context->protocol->get_info(context, &io);
	if (rc < 0) {
		return rc;
	}

	resp->args[0] = io.resp.api_version;
	if (io.resp.api_version == API_VERSION_1) {
		put_u16(&resp->args[1], io.resp.v1.read_window_size);
		put_u16(&resp->args[3], io.resp.v1.write_window_size);
	} else if (io.resp.api_version >= API_VERSION_2) {
		resp->args[5] = io.resp.v2.block_size_shift;
		put_u16(&resp->args[6], io.resp.v2.timeout);
	}

	return 0;
}

/*
 * Command: GET_FLASH_INFO
 * Get the flash size and erase granularity
 *
 * V1:
 * RESP[0:3]: Flash Size (bytes)
 * RESP[4:7]: Erase Size (bytes)
 * V2:
 * RESP[0:1]: Flash Size (number of blocks)
 * RESP[2:3]: Erase Size (number of blocks)
 */
int mbox_handle_flash_info(struct mbox_context *context,
				  union mbox_regs *req, struct mbox_msg *resp)
{
	struct protocol_get_flash_info io;
	int rc;

	rc = context->protocol->get_flash_info(context, &io);
	if (rc < 0) {
		return rc;
	}

	switch (context->version) {
	case API_VERSION_1:
		/* Both Sizes in Bytes */
		put_u32(&resp->args[0], io.resp.v1.flash_size);
		put_u32(&resp->args[4], io.resp.v1.erase_size);
		break;
	case API_VERSION_2:
		/* Both Sizes in Block Size */
		put_u16(&resp->args[0], io.resp.v2.flash_size);
		put_u16(&resp->args[2], io.resp.v2.erase_size);
		break;
	default:
		MSG_ERR("API Version Not Valid - Invalid System State\n");
		return -MBOX_R_SYSTEM_ERROR;
	}

	return 0;
}

/*
 * get_lpc_addr_shifted() - Get lpc address of the current window
 * @context:		The mbox context pointer
 *
 * Return:	The lpc address to access that offset shifted by block size
 */
static inline uint16_t get_lpc_addr_shifted(struct mbox_context *context)
{
	uint32_t lpc_addr, mem_offset;

	/* Offset of the current window in the reserved memory region */
	mem_offset = context->current->mem - context->mem;
	/* Total LPC Address */
	lpc_addr = context->lpc_base + mem_offset;

	MSG_DBG("LPC address of current window: 0x%.8x\n", lpc_addr);

	return lpc_addr >> context->block_size_shift;
}

int mbox_handle_create_window(struct mbox_context *context, bool ro,
			      union mbox_regs *req, struct mbox_msg *resp)
{
	struct protocol_create_window io;
	int rc;

	io.req.offset = get_u16(&req->msg.args[0]);
	io.req.ro = ro;

	rc = context->protocol->create_window(context, &io);
	if (rc < 0) {
		return rc;
	}

	put_u16(&resp->args[0], io.resp.lpc_address);
	if (context->version >= API_VERSION_2) {
		put_u16(&resp->args[2], io.resp.size);
		put_u16(&resp->args[4], io.resp.offset);
	}

	return 0;
}

/*
 * Command: CREATE_READ_WINDOW
 * Opens a read window
 * First checks if any current window with the requested data, if so we just
 * point the host to that. Otherwise we read the request data in from flash and
 * point the host there.
 *
 * V1:
 * ARGS[0:1]: Window Location as Offset into Flash (number of blocks)
 *
 * RESP[0:1]: LPC bus address for host to access this window (number of blocks)
 *
 * V2:
 * ARGS[0:1]: Window Location as Offset into Flash (number of blocks)
 * ARGS[2:3]: Requested window size (number of blocks)
 *
 * RESP[0:1]: LPC bus address for host to access this window (number of blocks)
 * RESP[2:3]: Actual window size that the host can access (number of blocks)
 */
int mbox_handle_read_window(struct mbox_context *context,
				   union mbox_regs *req, struct mbox_msg *resp)
{
	return mbox_handle_create_window(context, true, req, resp);
}

/*
 * Command: CREATE_WRITE_WINDOW
 * Opens a write window
 * First checks if any current window with the requested data, if so we just
 * point the host to that. Otherwise we read the request data in from flash and
 * point the host there.
 *
 * V1:
 * ARGS[0:1]: Window Location as Offset into Flash (number of blocks)
 *
 * RESP[0:1]: LPC bus address for host to access this window (number of blocks)
 *
 * V2:
 * ARGS[0:1]: Window Location as Offset into Flash (number of blocks)
 * ARGS[2:3]: Requested window size (number of blocks)
 *
 * RESP[0:1]: LPC bus address for host to access this window (number of blocks)
 * RESP[2:3]: Actual window size that was mapped/host can access (n.o. blocks)
 */
int mbox_handle_write_window(struct mbox_context *context,
				    union mbox_regs *req, struct mbox_msg *resp)
{
	return mbox_handle_create_window(context, false, req, resp);
}

/*
 * Commands: MARK_WRITE_DIRTY
 * Marks a portion of the current (write) window dirty, informing the daemon
 * that is has been written to and thus must be at some point written to the
 * backing store
 * These changes aren't written back to the backing store unless flush is then
 * called or the window closed
 *
 * V1:
 * ARGS[0:1]: Where within flash to start (number of blocks)
 * ARGS[2:5]: Number to mark dirty (number of bytes)
 *
 * V2:
 * ARGS[0:1]: Where within window to start (number of blocks)
 * ARGS[2:3]: Number to mark dirty (number of blocks)
 */
int mbox_handle_dirty_window(struct mbox_context *context,
				    union mbox_regs *req, struct mbox_msg *resp)
{
	struct protocol_mark_dirty io;

	if (context->version == API_VERSION_1) {
		io.req.v1.offset = get_u16(&req->msg.args[0]);
		io.req.v1.size = get_u32(&req->msg.args[2]);
	} else {
		io.req.v2.offset = get_u16(&req->msg.args[0]);
		io.req.v2.size = get_u16(&req->msg.args[2]);
	}

	return context->protocol->mark_dirty(context, &io);
}

/*
 * Commands: MARK_WRITE_ERASE
 * Erases a portion of the current window
 * These changes aren't written back to the backing store unless flush is then
 * called or the window closed
 *
 * V1:
 * Unimplemented
 *
 * V2:
 * ARGS[0:1]: Where within window to start (number of blocks)
 * ARGS[2:3]: Number to erase (number of blocks)
 */
int mbox_handle_erase_window(struct mbox_context *context,
				    union mbox_regs *req, struct mbox_msg *resp)
{
	struct protocol_erase io;

	io.req.offset = get_u16(&req->msg.args[0]);
	io.req.size = get_u16(&req->msg.args[2]);

	if (!context->protocol->erase) {
		MSG_ERR("Protocol Version invalid for Erase Command\n");
		return -ENOTSUP;
	}

	return context->protocol->erase(context, &io);
}

/*
 * Command: WRITE_FLUSH
 * Flushes any dirty or erased blocks in the current window back to the backing
 * store
 * NOTE: For V1 this behaves much the same as the dirty command in that it
 * takes an offset and number of blocks to dirty, then also performs a flush as
 * part of the same command. For V2 this will only flush blocks already marked
 * dirty/erased with the appropriate commands and doesn't take any arguments
 * directly.
 *
 * V1:
 * ARGS[0:1]: Where within window to start (number of blocks)
 * ARGS[2:5]: Number to mark dirty (number of bytes)
 *
 * V2:
 * NONE
 */
int mbox_handle_flush_window(struct mbox_context *context,
				    union mbox_regs *req, struct mbox_msg *resp)
{
	struct protocol_flush io = { 0 };

	if (context->version == API_VERSION_1) {
		io.req.offset = get_u16(&req->msg.args[0]);
		io.req.size = get_u32(&req->msg.args[2]);
	}

	return context->protocol->flush(context, &io);
}

/*
 * Command: CLOSE_WINDOW
 * Close the current window
 * NOTE: There is an implicit flush
 *
 * V1:
 * NONE
 *
 * V2:
 * ARGS[0]: FLAGS
 */
int mbox_handle_close_window(struct mbox_context *context,
				    union mbox_regs *req, struct mbox_msg *resp)
{
	struct protocol_close io = { 0 };

	if (context->version >= API_VERSION_2) {
		io.req.flags = req->msg.args[0];
	}

	return context->protocol->close(context, &io);
}

/*
 * Command: BMC_EVENT_ACK
 * Sent by the host to acknowledge BMC events supplied in mailbox register 15
 *
 * ARGS[0]: Bitmap of bits to ack (by clearing)
 */
int mbox_handle_ack(struct mbox_context *context, union mbox_regs *req,
			   struct mbox_msg *resp)
{
	struct protocol_ack io;

	io.req.flags = req->msg.args[0];

	return context->protocol->ack(context, &io);
}

/*
 * check_req_valid() - Check if the given request is a valid mbox request
 * @context:	The mbox context pointer
 * @cmd:	The request registers
 *
 * Return:	0 if request is valid otherwise negative error code
 */
static int check_req_valid(struct mbox_context *context, union mbox_regs *req)
{
	uint8_t cmd = req->msg.command;
	uint8_t seq = req->msg.seq;

	if (cmd > NUM_MBOX_CMDS) {
		MSG_ERR("Unknown mbox command: %d\n", cmd);
		return -ENOTSUP;
	}

	if (seq == context->prev_seq && cmd != MBOX_C_GET_MBOX_INFO) {
		MSG_ERR("Invalid sequence number: %d, previous: %d\n", seq,
			context->prev_seq);
		return -EBADMSG;
	}

	if (context->state & STATE_SUSPENDED) {
		if (cmd != MBOX_C_GET_MBOX_INFO && cmd != MBOX_C_ACK) {
			MSG_ERR("Cannot use that cmd while suspended: %d\n",
				cmd);
			return -EBUSY;
		}
	}

	if (!(context->state & MAPS_MEM)) {
		if (cmd != MBOX_C_RESET_STATE && cmd != MBOX_C_GET_MBOX_INFO
					      && cmd != MBOX_C_ACK) {
			MSG_ERR("Must call GET_MBOX_INFO before %d\n", cmd);
			return -EPROTO;
		}
	}

	return 0;
}

static const mboxd_mbox_handler mbox_handlers[] = {
	mbox_handle_reset,
	mbox_handle_mbox_info,
	mbox_handle_flash_info,
	mbox_handle_read_window,
	mbox_handle_close_window,
	mbox_handle_write_window,
	mbox_handle_dirty_window,
	mbox_handle_flush_window,
	mbox_handle_ack,
	mbox_handle_erase_window
};

/*
 * handle_mbox_req() - Handle an incoming mbox command request
 * @context:	The mbox context pointer
 * @req:	The mbox request message
 *
 * Return:	0 if handled successfully otherwise negative error code
 */
static int handle_mbox_req(struct mbox_context *context, union mbox_regs *req)
{
	struct mbox_msg resp = {
		.command = req->msg.command,
		.seq = req->msg.seq,
		.args = { 0 },
		.response = MBOX_R_SUCCESS
	};
	int rc = 0, len, i;

	MSG_INFO("Received MBOX command: %u\n", req->msg.command);
	rc = check_req_valid(context, req);
	if (!rc) {
		/* Commands start at 1 so we have to subtract 1 from the cmd */
		mboxd_mbox_handler h = context->handlers[req->msg.command - 1];
		rc = h(context, req, &resp);
		if (rc < 0) {
			MSG_ERR("Error handling mbox cmd: %d\n",
				req->msg.command);
		}
	}

	rc = mbox_xlate_errno(context, rc);
	resp.response = rc;
	context->prev_seq = req->msg.seq;

	MSG_DBG("Writing MBOX response:\n");
	MSG_DBG("MBOX cmd: %u\n", resp.command);
	MSG_DBG("MBOX seq: %u\n", resp.seq);
	for (i = 0; i < MBOX_ARGS_BYTES; i++) {
		MSG_DBG("MBOX arg[%d]: 0x%.2x\n", i, resp.args[i]);
	}
	MSG_INFO("Writing MBOX response: %u\n", resp.response);
	len = write(context->fds[MBOX_FD].fd, &resp, sizeof(resp));
	if (len < sizeof(resp)) {
		MSG_ERR("Didn't write the full response\n");
		rc = -errno;
	}

	return rc;
}

/*
 * get_message() - Read an mbox request message from the mbox registers
 * @context:	The mbox context pointer
 * @msg:	Where to put the received message
 *
 * Return:	0 if read successfully otherwise negative error code
 */
static int get_message(struct mbox_context *context, union mbox_regs *msg)
{
	int rc, i;

	rc = read(context->fds[MBOX_FD].fd, msg, sizeof(msg->raw));
	if (rc < 0) {
		MSG_ERR("Couldn't read: %s\n", strerror(errno));
		return -errno;
	} else if (rc < sizeof(msg->raw)) {
		MSG_ERR("Short read: %d expecting %zu\n", rc, sizeof(msg->raw));
		return -1;
	}

	MSG_DBG("Received MBOX request:\n");
	MSG_DBG("MBOX cmd: %u\n", msg->msg.command);
	MSG_DBG("MBOX seq: %u\n", msg->msg.seq);
	for (i = 0; i < MBOX_ARGS_BYTES; i++) {
		MSG_DBG("MBOX arg[%d]: 0x%.2x\n", i, msg->msg.args[i]);
	}

	return 0;
}

/*
 * dispatch_mbox() - handle an mbox interrupt
 * @context:	The mbox context pointer
 *
 * Return:	0 if handled successfully otherwise negative error code
 */
int dispatch_mbox(struct mbox_context *context)
{
	int rc = 0;
	union mbox_regs req = { 0 };

	assert(context);

	rc = get_message(context, &req);
	if (rc) {
		return rc;
	}

	return handle_mbox_req(context, &req);
}

int __init_mbox_dev(struct mbox_context *context, const char *path)
{
	int fd;

	context->handlers = mbox_handlers;

	/* Open MBOX Device */
	fd = open(path, O_RDWR | O_NONBLOCK);
	if (fd < 0) {
		MSG_ERR("Couldn't open %s with flags O_RDWR: %s\n",
			path, strerror(errno));
		return -errno;
	}
	MSG_DBG("Opened mbox dev: %s\n", path);

	context->fds[MBOX_FD].fd = fd;

	return 0;
}

int init_mbox_dev(struct mbox_context *context)
{
	return __init_mbox_dev(context, MBOX_HOST_PATH);
}

void free_mbox_dev(struct mbox_context *context)
{
	close(context->fds[MBOX_FD].fd);
}
