/*
 * Mailbox Daemon LPC Helpers
 *
 * 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.
 *
 */

#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 "mboxd_lpc.h"
#include "mboxd_flash.h"
#include <linux/aspeed-lpc-ctrl.h>

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

int __init_lpc_dev(struct mbox_context *context, const char *path)
{
	struct aspeed_lpc_ctrl_mapping map = {
		.window_type = ASPEED_LPC_CTRL_WINDOW_MEMORY,
		.window_id = 0, /* There's only one */
		.flags = 0,
		.addr = 0,
		.offset = 0,
		.size = 0
	};
	int fd;

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

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

	/* Find Size of Reserved Memory Region */
	MSG_DBG("Getting buffer size...\n");
	if (ioctl(fd, ASPEED_LPC_CTRL_IOCTL_GET_SIZE, &map) < 0) {
		MSG_ERR("Couldn't get lpc control buffer size: %s\n",
			strerror(errno));
		return -errno;
	}

	context->mem_size = map.size;
	/* Map at the top of the 28-bit LPC firmware address space-0 */
	context->lpc_base = 0x0FFFFFFF & -context->mem_size;

	/* mmap the Reserved Memory Region */
	MSG_DBG("Mapping in 0x%.8x bytes of %s\n", context->mem_size, path);
	context->mem = mmap(NULL, context->mem_size, PROT_READ | PROT_WRITE,
				MAP_SHARED, fd, 0);
	if (context->mem == MAP_FAILED) {
		MSG_ERR("Failed to map %s: %s\n", path, strerror(errno));
		return -errno;
	}

	return 0;
}

int init_lpc_dev(struct mbox_context *context)
{
	return __init_lpc_dev(context, LPC_CTRL_PATH);
}

void free_lpc_dev(struct mbox_context *context)
{
	if (context->mem) {
		munmap(context->mem, context->mem_size);
	}
	close(context->fds[LPC_CTRL_FD].fd);
}

/*
 * point_to_flash() - Point the lpc bus mapping to the actual flash device
 * @context:	The mbox context pointer
 *
 * Return:	0 on success otherwise negative error code
 */
int point_to_flash(struct mbox_context *context)
{
	struct aspeed_lpc_ctrl_mapping map = {
		.window_type = ASPEED_LPC_CTRL_WINDOW_FLASH,
		.window_id = 0, /* Theres only one */
		.flags = 0,
		/*
		 * The mask is because the top nibble is the host LPC FW space,
		 * we want space 0.
		 */
		.addr = 0x0FFFFFFF & -context->flash_size,
		.offset = 0,
		.size = context->flash_size
	};

	if (context->state & MAPS_FLASH) {
		return 0; /* LPC Bus already points to flash */
	}
	/* Don't let the host access flash while we're suspended */
	if (context->state & STATE_SUSPENDED) {
		MSG_ERR("Can't point lpc mapping to flash while suspended\n");
		return -MBOX_R_PARAM_ERROR;
	}

	MSG_INFO("Pointing HOST LPC bus at the flash\n");
	MSG_INFO("Assuming %dMB of flash: HOST LPC 0x%08x\n",
		context->flash_size >> 20, map.addr);

	if (ioctl(context->fds[LPC_CTRL_FD].fd, ASPEED_LPC_CTRL_IOCTL_MAP, &map)
			== -1) {
		MSG_ERR("Failed to point the LPC BUS at the actual flash: %s\n",
			strerror(errno));
		return -MBOX_R_SYSTEM_ERROR;
	}

	context->state = ACTIVE_MAPS_FLASH;
	/*
	 * Since the host now has access to the flash it can change it out from
	 * under us
	 */
	return set_flash_bytemap(context, 0, context->flash_size, FLASH_DIRTY);
}

/*
 * point_to_memory() - Point the lpc bus mapping to the reserved memory region
 * @context:	The mbox context pointer
 *
 * Return:	0 on success otherwise negative error code
 */
int point_to_memory(struct mbox_context *context)
{
	struct aspeed_lpc_ctrl_mapping map = {
		.window_type = ASPEED_LPC_CTRL_WINDOW_MEMORY,
		.window_id = 0, /* There's only one */
		.flags = 0,
		.addr = context->lpc_base,
		.offset = 0,
		.size = context->mem_size
	};

	if (context->state & MAPS_MEM) {
		return 0; /* LPC Bus already points to reserved memory area */
	}

	MSG_INFO("Pointing HOST LPC bus at memory region %p of size 0x%.8x\n",
			context->mem, context->mem_size);
	MSG_INFO("LPC address 0x%.8x\n", map.addr);

	if (ioctl(context->fds[LPC_CTRL_FD].fd, ASPEED_LPC_CTRL_IOCTL_MAP,
		  &map)) {
		MSG_ERR("Failed to point the LPC BUS to memory: %s\n",
			strerror(errno));
		return -MBOX_R_SYSTEM_ERROR;
	}

	/* LPC now maps memory (keep suspended state) */
	context->state = MAPS_MEM | (context->state & STATE_SUSPENDED);

	return 0;
}
