/* Copyright 2016 IBM
 *
 * 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.
 *
 */

#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 <mtd/mtd-abi.h>

#include <linux/aspeed-lpc-ctrl.h>

#include "mbox.h"
#include "common.h"

#define LPC_CTRL_PATH "/dev/aspeed-lpc-ctrl"

#define MBOX_FD 0
#define LPC_CTRL_FD 1
#define MTD_FD 2
#define TOTAL_FDS 3

#define ALIGN_UP(_v, _a)    (((_v) + (_a) - 1) & ~((_a) - 1))

#define MSG_OUT(f_, ...) do { if (verbosity != MBOX_LOG_NONE) { mbox_log(LOG_INFO, f_, ##__VA_ARGS__); } } while(0)
#define MSG_ERR(f_, ...) do { if (verbosity != MBOX_LOG_NONE) { mbox_log(LOG_ERR, f_, ##__VA_ARGS__); } } while(0)

#define BOOT_HICR7 0x30000e00U
#define BOOT_HICR8 0xfe0001ffU

struct mbox_context {
	struct pollfd fds[TOTAL_FDS];
	void *lpc_mem;
	uint32_t base;
	uint32_t size;
	uint32_t pgsize;
	bool dirty;
	uint32_t dirtybase;
	uint32_t dirtysize;
	struct mtd_info_user mtd_info;
};

static int running = 1;
static int sighup = 0;

static int point_to_flash(struct mbox_context *context)
{
	struct aspeed_lpc_ctrl_mapping map;
	int r = 0;

	/*
	 * Point it to the real flash for sanity.
	 *
	 * This function assumes 32MB of flash which means that that
	 * hostboot expects flash to be at 0x0e000000 - 0x0fffffff on the
	 * LPC bus. If the machine actually has 64MB of flash then the
	 * map.addr should be 0x0c000000. TODO
	 *
	 * Until hostboot learns how to talk to this daemon this hardcode will
	 * get hostboot going. Furthermore, when hostboot does learn to talk
	 * then this mapping is unnecessary and this code should be removed.
	 */

	map.addr = 0x0e000000;
	map.size = 0x02000000; /* 32MB */
	map.offset = 0;
	map.window_type = ASPEED_LPC_CTRL_WINDOW_FLASH;
	map.window_id = 0; /* Theres only one */

	MSG_OUT("Pointing HOST LPC bus at the actual flash\n");
	MSG_OUT("Assuming 32MB of flash: HOST LPC 0x%08x\n", map.addr);

	if (ioctl(context->fds[LPC_CTRL_FD].fd, ASPEED_LPC_CTRL_IOCTL_MAP, &map) == -1) {
		r = -errno;
		MSG_ERR("Couldn't MAP the host LPC bus to the platform flash\n");
	}

	return r;
}

static int flash_write(struct mbox_context *context, uint32_t pos, uint32_t len)
{
	int rc;
	struct erase_info_user erase_info = {
		.start = pos,
	};

	assert(context);

	erase_info.length = ALIGN_UP(len, context->mtd_info.erasesize);

	MSG_OUT("Erasing 0x%08x for 0x%08x (aligned: 0x%08x)\n", pos, len, erase_info.length);
	if (ioctl(-context->fds[MTD_FD].fd, MEMERASE, &erase_info) == -1) {
		MSG_ERR("Couldn't MEMERASE ioctl, flash write lost: %s\n", strerror(errno));
		return -1;
	}

	if (lseek(-context->fds[MTD_FD].fd, pos, SEEK_SET) == (off_t) -1) {
		MSG_ERR("Couldn't seek to 0x%08x into MTD, flash write lost: %s\n", pos, strerror(errno));
		return -1;
	}

	while (erase_info.length) {
		rc = write(-context->fds[MTD_FD].fd, context->lpc_mem + pos, erase_info.length);
		if (rc == -1) {
			MSG_ERR("Couldn't write to flash! Flash write lost: %s\n", strerror(errno));
			return -1;
		}
		erase_info.length -= rc;
		pos += rc;
	}

	return 0;
}

/* TODO: Add come consistency around the daemon exiting and either
 * way, ensuring it responds.
 * I'm in favour of an approach where it does its best to stay alive
 * and keep talking, the hacky prototype was written the other way.
 * This function is now inconsistent
 */
static int dispatch_mbox(struct mbox_context *context)
{
	int r = 0;
	int len;
	off_t pos;
	uint8_t byte;
	union mbox_regs resp, req = { 0 };
	uint16_t sizepg, basepg, dirtypg;
	uint32_t dirtycount;
	struct aspeed_lpc_ctrl_mapping map;

	assert(context);

	map.addr = context->base;
	map.size = context->size;
	map.offset = 0;
	map.window_type = ASPEED_LPC_CTRL_WINDOW_MEMORY;
	map.window_id = 0; /* Theres only one */

	MSG_OUT("Dispatched to mbox\n");
	r = read(context->fds[MBOX_FD].fd, &req, sizeof(req.raw));
	if (r < 0) {
		r = -errno;
		MSG_ERR("Couldn't read: %s\n", strerror(errno));
		goto out;
	}
	if (r < sizeof(req.msg)) {
		MSG_ERR("Short read: %d expecting %zu\n", r, sizeof(req.msg));
		r = -1;
		goto out;
	}

	/* We are NOT going to update the last two 'status' bytes */
	memcpy(&resp, &req, sizeof(req.msg));

	sizepg = context->size >> context->pgsize;
	basepg = context->base >> context->pgsize;
	MSG_OUT("Got data in with command %d\n", req.msg.command);
	switch (req.msg.command) {
		case MBOX_C_RESET_STATE:
			/* Called by early hostboot? TODO */
			resp.msg.response = MBOX_R_SUCCESS;
			r = point_to_flash(context);
			if (r) {
				resp.msg.response = MBOX_R_SYSTEM_ERROR;
				MSG_ERR("Couldn't point the LPC BUS back to actual flash\n");
			}
			break;
		case MBOX_C_GET_MBOX_INFO:
			/* TODO Freak if data.data[0] isn't 1 */
			resp.msg.data[0] = 1;
			put_u16(&resp.msg.data[1], sizepg);
			put_u16(&resp.msg.data[3], sizepg);
			resp.msg.response = MBOX_R_SUCCESS;
			/* Wow that can't stay negated thats horrible */
			MSG_OUT("LPC_CTRL_IOCTL_MAP to 0x%08x for 0x%08x\n", map.addr, map.size);
			r = ioctl(-context->fds[LPC_CTRL_FD].fd,
					ASPEED_LPC_CTRL_IOCTL_MAP, &map);
			if (r < 0) {
				r = -errno;
				resp.msg.response = MBOX_R_SYSTEM_ERROR;
				MSG_ERR("Couldn't MAP ioctl(): %s\n", strerror(errno));
			}
			break;
		case MBOX_C_GET_FLASH_INFO:
			put_u32(&resp.msg.data[0], context->mtd_info.size);
			put_u32(&resp.msg.data[4], context->mtd_info.erasesize);
			resp.msg.response = MBOX_R_SUCCESS;
			break;
		case MBOX_C_READ_WINDOW:
			/*
			 * We could probably play tricks with LPC mapping.
			 * That would require kernel involvement.
			 * We could also always copy the relevant flash part to
			 * context->base even if it turns out that offset is in
			 * the window...
			 * This approach is easiest.
			 */
			if (context->dirty) {
				r = read(-context->fds[MTD_FD].fd, context->lpc_mem, context->size);
				if (r != context->size) {
					MSG_ERR("Short read: %d expecting %"PRIu32"\n", r, context->size);
					goto out;
				}
			}
			basepg += get_u16(&req.msg.data[0]);
			put_u16(&resp.msg.data[0], basepg);
			resp.msg.response = MBOX_R_SUCCESS;
			context->dirty = false;
			break;
		case MBOX_C_CLOSE_WINDOW:
			context->dirty = true;
			break;
		case MBOX_C_WRITE_WINDOW:
			basepg += get_u16(&req.msg.data[0]);
			put_u16(&resp.msg.data[0], basepg);
			resp.msg.response = MBOX_R_SUCCESS;
			context->dirtybase = basepg << context->pgsize;
			break;
		/* Optimise these later */
		case MBOX_C_WRITE_DIRTY:
		case MBOX_C_WRITE_FENCE:
			dirtypg = get_u16(&req.msg.data[0]);
			dirtycount = get_u32(&req.msg.data[2]);
			if (dirtycount == 0) {
				resp.msg.response = MBOX_R_PARAM_ERROR;
				break;
			}
			/*
			 * dirtypg is actually offset within window so we probs
			 * need to know if the window isn't at zero
			 */
			if (flash_write(context, dirtypg << context->pgsize, dirtycount) != 0) {
				resp.msg.response = MBOX_R_WRITE_ERROR;
				break;
			}
			resp.msg.response = MBOX_R_SUCCESS;
			break;
		case MBOX_C_ACK:
			resp.msg.response = MBOX_R_SUCCESS;
			pos = lseek(context->fds[MBOX_FD].fd, MBOX_BMC_BYTE, SEEK_SET);
			if (pos != MBOX_BMC_BYTE) {
				r = -errno;
				MSG_ERR("Couldn't lseek() to byte %d: %s\n", MBOX_BMC_BYTE,
						strerror(errno));
			}
			/*
			 * NAND what is in the hardware and the request.
			 * This prevents the host being able to SET bits, it can
			 * only request set ones be cleared.
			 */
			byte = ~(req.msg.data[0] & req.raw[MBOX_BMC_BYTE]);
			len = write(context->fds[MBOX_FD].fd, &byte, 1);
			if (len != 1) {
				r = -errno;
				MSG_ERR("Couldn't write to BMC status reg: %s\n",
						strerror(errno));
			}
			pos = lseek(context->fds[MBOX_FD].fd, 0, SEEK_SET);
			if (pos != 0) {
				r = -errno;
				MSG_ERR("Couldn't reset MBOX offset to zero\n");
			}
			break;
		case MBOX_C_COMPLETED_COMMANDS:
			/* This implementation always completes before responding */
			resp.msg.data[0] = 0;
			resp.msg.response = MBOX_R_SUCCESS;
			break;
		default:
			MSG_ERR("UNKNOWN MBOX COMMAND\n");
			resp.msg.response = MBOX_R_PARAM_ERROR;
			r = -1;
	}

	MSG_OUT("Writing response to MBOX regs\n");
	len = write(context->fds[MBOX_FD].fd, &resp, sizeof(resp.msg));
	if (len < sizeof(resp.msg)) {
		r = -errno;
		MSG_ERR("Didn't write the full response\n");
	}

out:
	return r;
}

int copy_flash(struct mbox_context *context)
{
	int r;

	/*
	 * Copy flash into RAM early, same time.
	 * The kernel has created the LPC->AHB mapping also, which means
	 * flash should work.
	 * Ideally we tell the kernel whats up and when to do stuff...
	 */
	MSG_OUT("Loading flash into ram at %p for 0x%08x bytes\n",
		context->lpc_mem, context->size);
	if (lseek(context->fds[MTD_FD].fd, 0, SEEK_SET) != 0) {
		r = -errno;
		MSG_ERR("Couldn't reset MBOX pos to zero\n");
		return r;
	}
	r = read(context->fds[MTD_FD].fd, context->lpc_mem, context->size);
	if (r != context->size) {
		r = -errno;
		MSG_ERR("Couldn't copy mtd into ram: %d\n", r);
		return r;
	}
	return 0;
}

void signal_hup(int signum, siginfo_t *info, void *uc)
{
	sighup = 1;
}

static void usage(const char *name)
{
	fprintf(stderr, "Usage %s [ -v[v] | --syslog ]\n", name);
	fprintf(stderr, "\t--verbose\t Be [more] verbose\n");
	fprintf(stderr, "\t--syslog\t Log output to syslog (pointless without -v)\n\n");
}

int main(int argc, char *argv[])
{
	struct mbox_context *context;
	const char *name = argv[0];
	char *pnor_filename = NULL;
	int opt, polled, r, i;
	struct aspeed_lpc_ctrl_mapping map;
	struct sigaction act;

	static const struct option long_options[] = {
		{ "verbose", no_argument, 0, 'v' },
		{ "syslog",  no_argument, 0, 's' },
		{ 0,	     0,		  0,  0  }
	};

	context = calloc(1, sizeof(*context));
	for (i = 0; i < TOTAL_FDS; i++)
		context->fds[i].fd = -1;

	mbox_vlog = &mbox_log_console;
	while ((opt = getopt_long(argc, argv, "v", long_options, NULL)) != -1) {
		switch (opt) {
			case 0:
				break;
			case 'v':
				verbosity++;
				break;
			case 's':
				/* Avoid a double openlog() */
				if (mbox_vlog != &vsyslog) {
					openlog(PREFIX, LOG_ODELAY, LOG_DAEMON);
					mbox_vlog = &vsyslog;
				}
				break;
			default:
				usage(name);
				exit(EXIT_FAILURE);
		}
	}

	if (verbosity == MBOX_LOG_VERBOSE)
		MSG_OUT("Verbose logging\n");

	if (verbosity == MBOX_LOG_DEBUG)
		MSG_OUT("Debug logging\n");

	MSG_OUT("Registering SigHUP hander\n");
	act.sa_sigaction = signal_hup;
	sigemptyset(&act.sa_mask);
	act.sa_flags = SA_SIGINFO;
	if (sigaction(SIGHUP, &act, NULL) < 0) {
		perror("Registering SIGHUP");
		exit(1);
	}
	sighup = 0;

	MSG_OUT("Starting\n");

	MSG_OUT("Opening %s\n", MBOX_HOST_PATH);
	context->fds[MBOX_FD].fd = open(MBOX_HOST_PATH, O_RDWR | O_NONBLOCK);
	if (context->fds[MBOX_FD].fd < 0) {
		r = -errno;
		MSG_ERR("Couldn't open %s with flags O_RDWR: %s\n",
				MBOX_HOST_PATH, strerror(errno));
		goto finish;
	}

	MSG_OUT("Opening %s\n", LPC_CTRL_PATH);
	context->fds[LPC_CTRL_FD].fd = open(LPC_CTRL_PATH, O_RDWR | O_SYNC);
	if (context->fds[LPC_CTRL_FD].fd < 0) {
		r = -errno;
		MSG_ERR("Couldn't open %s with flags O_RDWR: %s\n",
				LPC_CTRL_PATH, strerror(errno));
		goto finish;
	}

	MSG_OUT("Getting buffer size...\n");
	/* This may become more variable in the future */
	context->pgsize = 12; /* 4K */
	map.window_type = ASPEED_LPC_CTRL_WINDOW_MEMORY;
	map.window_id = 0; /* Theres only one */
	if (ioctl(context->fds[LPC_CTRL_FD].fd, ASPEED_LPC_CTRL_IOCTL_GET_SIZE,
				&map) < 0) {
		r = -errno;
		MSG_OUT("fail\n");
		MSG_ERR("Couldn't get lpc control buffer size: %s\n", strerror(-r));
		goto finish;
	}
	/* And strip the first nibble, LPC access speciality */
	context->size = map.size;
	context->base = -context->size & 0x0FFFFFFF;

	/* READ THE COMMENT AT THE START OF THIS FUNCTION! */
	r = point_to_flash(context);
	if (r) {
		MSG_ERR("Failed to point the LPC BUS at the actual flash: %s\n",
				strerror(-r));
		goto finish;
	}

	MSG_OUT("Mapping %s for %u\n", LPC_CTRL_PATH, context->size);
	context->lpc_mem = mmap(NULL, context->size, PROT_READ | PROT_WRITE, MAP_SHARED,
			context->fds[LPC_CTRL_FD].fd, 0);
	if (context->lpc_mem == MAP_FAILED) {
		r = -errno;
		MSG_ERR("Didn't manage to mmap %s: %s\n", LPC_CTRL_PATH, strerror(errno));
		goto finish;
	}

	pnor_filename = get_dev_mtd();
	if (!pnor_filename) {
		MSG_ERR("Couldn't find the PNOR /dev/mtd partition\n");
		r = -1;
		goto finish;
	}

	MSG_OUT("Opening %s\n", pnor_filename);
	context->fds[MTD_FD].fd = open(pnor_filename, O_RDWR);
	if (context->fds[MTD_FD].fd < 0) {
		r = -errno;
		MSG_ERR("Couldn't open %s with flags O_RDWR: %s\n",
				pnor_filename, strerror(errno));
		goto finish;
	}

	if (ioctl(context->fds[MTD_FD].fd, MEMGETINFO, &context->mtd_info) == -1) {
		MSG_ERR("Couldn't get information about MTD: %s\n", strerror(errno));
		return -1;
	}

	if (copy_flash(context))
		goto finish;

	context->fds[MBOX_FD].events = POLLIN;
	/* Ignore in poll() */
	context->fds[LPC_CTRL_FD].fd = -context->fds[LPC_CTRL_FD].fd;
	context->fds[MTD_FD].fd = -context->fds[MTD_FD].fd;

	/* Test the single write facility by setting all the regs to 0xFF */
	MSG_OUT("Setting all MBOX regs to 0xff individually...\n");
	for (i = 0; i < MBOX_REG_BYTES; i++) {
		uint8_t byte = 0xff;
		off_t pos;
		int len;

		pos = lseek(context->fds[MBOX_FD].fd, i, SEEK_SET);
		if (pos != i) {
			MSG_ERR("Couldn't lseek() to byte %d: %s\n", i,
					strerror(errno));
			break;
		}
		len = write(context->fds[MBOX_FD].fd, &byte, 1);
		if (len != 1) {
			MSG_ERR("Couldn't write MBOX reg %d: %s\n", i,
					strerror(errno));
			break;
		}
	}
	if (lseek(context->fds[MBOX_FD].fd, 0, SEEK_SET) != 0) {
		r = -errno;
		MSG_ERR("Couldn't reset MBOX pos to zero\n");
		goto finish;
	}

	MSG_OUT("Entering polling loop\n");
	while (running) {
		polled = poll(context->fds, TOTAL_FDS, 1000);
		if (polled == 0)
			continue;
		if ((polled == -1) && (errno != -EINTR) && (sighup == 1)) {
			/* Got sighup. reset to point to flash and
			 * reread flash */
			context->fds[LPC_CTRL_FD].fd = -context->fds[LPC_CTRL_FD].fd;
			r = point_to_flash(context);
			if (r) {
				goto finish;
			}
			context->fds[LPC_CTRL_FD].fd = -context->fds[LPC_CTRL_FD].fd;
			context->fds[MTD_FD].fd = -context->fds[MTD_FD].fd;
			r = copy_flash(context);
			if (r)
				goto finish;
			context->fds[MTD_FD].fd = -context->fds[MTD_FD].fd;
			sighup = 0;
			continue;
		}
		if (polled < 0) {
			r = -errno;
			MSG_ERR("Error from poll(): %s\n", strerror(errno));
			break;
		}
		r = dispatch_mbox(context);
		if (r < 0) {
			MSG_ERR("Error handling MBOX event: %s\n", strerror(-r));
			break;
		}
	}

	MSG_OUT("Exiting\n");

	/* Unnegate so we can close it */
	context->fds[LPC_CTRL_FD].fd = -context->fds[LPC_CTRL_FD].fd;
	context->fds[MTD_FD].fd = -context->fds[MTD_FD].fd;

finish:
	if (context->lpc_mem)
		munmap(context->lpc_mem, context->size);

	free(pnor_filename);
	close(context->fds[MTD_FD].fd);
	close(context->fds[LPC_CTRL_FD].fd);
	close(context->fds[MBOX_FD].fd);
	free(context);

	return r;
}

