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

#define _GNU_SOURCE /* fallocate */
#include <assert.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include "mbox.h"
#include "mboxd_flash.h"
#include "mboxd_lpc.h"
#include "mboxd_msg.h"
#include "mboxd_windows.h"

#include "test/mbox.h"

#define STEP 16

void dump_buf(const void *buf, size_t len)
{
	const uint8_t *buf8 = buf;
	int i;

	for (i = 0; i < len; i += STEP) {
		int delta;
		int max;
		int j;

		delta = len - i;
		max = delta > STEP ? STEP : delta;

		printf("0x%08x:\t", i);
		for (j = 0; j < max; j++)
			printf("0x%02x, ", buf8[i + j]);

		printf("\n");
	}
	printf("\n");
}

/*
 * Because we are using a file and not a pipe for the mbox file descriptor we
 * need to handle a difference in behaviour. For a given command and response
 * sequence the first 16 bytes of the file are occupied by the mbox command.
 * The response occupies the following 14 bytes for a total of 30 bytes.
 *
 * We also have to ensure we lseek() to reset the file descriptor offset back
 * to the start of the file before dispatching the mbox command.
 */

/* Macros for handling the pipe/file discrepancy */
#define RESPONSE_OFFSET	16
#define RESPONSE_SIZE	14

int mbox_cmp(struct mbox_context *context, const uint8_t *expected, size_t len)
{
	struct stat details;
	uint8_t *map;
	int rc;
	int fd;

	fd = context->fds[MBOX_FD].fd;
	fstat(fd, &details);

	map = mmap(NULL, details.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	assert(map != MAP_FAILED);
	assert(details.st_size >= (RESPONSE_OFFSET + len));

	rc = memcmp(expected, &map[RESPONSE_OFFSET], len);

	if (rc != 0) {
		printf("\nMBOX state (%ld):\n", details.st_size);
		dump_buf(map, details.st_size);
		printf("Expected response (%lu):\n", len);
		dump_buf(expected, len);
	}

	munmap(map, details.st_size);

	return rc;
}

void mbox_rspcpy(struct mbox_context *context, struct mbox_msg *msg)
{
	struct stat details;
	uint8_t *map;
	int fd;

	fd = context->fds[MBOX_FD].fd;
	fstat(fd, &details);

	map = mmap(NULL, details.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	assert(map != MAP_FAILED);
	assert(details.st_size >= (RESPONSE_OFFSET + RESPONSE_SIZE));

	memcpy(msg, &map[RESPONSE_OFFSET], RESPONSE_SIZE);

	munmap(map, details.st_size);
}

int mbox_command_write(struct mbox_context *context, const uint8_t *command,
		size_t len)
{
	size_t remaining;
	int rc;
	int fd;

	fd = context->fds[MBOX_FD].fd;
	rc = lseek(fd, 0, SEEK_SET);
	if (rc != 0)
		return -1;

	remaining = len;
	while (remaining > 0) {
		rc = write(fd, command, remaining);
		if (rc < 0)
			goto out;
		remaining -= rc;
	}

	rc = lseek(fd, 0, SEEK_SET);
	if (rc != 0)
		return -1;

out:
	return rc;
}

int mbox_command_dispatch(struct mbox_context *context, const uint8_t *command,
		size_t len)
{
	uint8_t status;
	int rc;

	rc = mbox_command_write(context, command, len);
	if (rc < 0)
		return rc;

	rc = dispatch_mbox(context);
	if (rc < 0)
		return -rc;

	/*
	 * The aspeed-lpc-ctrl driver implements mailbox register access
	 * through the usual read()/write() chardev interface.
	 *
	 * The typical access sequence is:
	 *
	 * 1. Read all the registers out
	 * 2. Perform the action specified
	 * 3. Write a response to the registers.
	 *
	 * For the tests the "device" file descriptor is backed by a temporary
	 * file. The above sequence leads to a file-size of 30 bytes: 16 bytes
	 * for the issued command, followed by a 14-byte response.
	 *
	 * However, the typical access pattern isn't the only access pattern.
	 * Individual byte registers can be accessed by lseek()'ing on the
	 * device's file descriptor and issuing read() or write() as desired.
	 * The daemon uses this property to manage the BMC status byte, and the
	 * implementation cleans up after status byte operations by lseek()'ing
	 * back to offset zero.
	 *
	 * Thus for the BMC_EVENT_ACK command the file only reaches a size of
	 * 16 bytes; the daemon's response overwrites the first 14 bytes of the
	 * command injected by the tests.
	 *
	 * The consequence of this is that the response status byte can either
	 * appear at offset 13, or offset 29, depending on the command.
	 *
	 * However, regardless of what command is issued the response data is
	 * written to the device and the file descriptor is left in the
	 * post-write() state. This means the status byte can always be
	 * accessed relative to the current position by an lseek() of type
	 * SEEK_CUR for offset -1.
	 *
	 */
	rc = lseek(context->fds[MBOX_FD].fd, -1, SEEK_CUR);
	if (rc < 0)
		return rc;

	rc = read(context->fds[MBOX_FD].fd, &status, sizeof(status));
	if (rc < 0)
		return rc;

	return status;
}

struct mbox_test_context {
	struct tmpf mbox;
	struct tmpf flash;
	struct tmpf lpc;
	struct mbox_context context;
} test;

void cleanup(void)
{
	tmpf_destroy(&test.mbox);
	tmpf_destroy(&test.flash);
	tmpf_destroy(&test.lpc);
}

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

struct mbox_context *mbox_create_test_context(int n_windows, size_t len)
{
	int rc;

	mbox_vlog = &mbox_log_console;
	verbosity = 2;

	atexit(cleanup);

	rc = tmpf_init(&test.mbox, "mbox-store.XXXXXX");
	assert(rc == 0);

	rc = tmpf_init(&test.flash, "flash-store.XXXXXX");
	assert(rc == 0);

	rc = tmpf_init(&test.lpc, "lpc-store.XXXXXX");
	assert(rc == 0);

	test.context.windows.num = n_windows;
	test.context.windows.default_size = len;

	/*
	 * We need to control MBOX_FD, so don't call __init_mbox_dev().
	 * Instead, insert our temporary file's fd directly into the context
	 */
	test.context.fds[MBOX_FD].fd = test.mbox.fd;

	rc = init_flash_dev(&test.context);
	assert(rc == 0);

	rc = fallocate(test.flash.fd, 0, 0, test.context.mtd_info.size);
	assert(rc == 0);

	rc = fallocate(test.lpc.fd, 0, 0, test.context.mtd_info.size);
	assert(rc == 0);

	rc = __init_lpc_dev(&test.context, test.lpc.path);
	assert(rc == 0);

	rc = init_windows(&test.context);
	assert(rc == 0);

	return rc ? NULL : &test.context;
}

/* From ccan's container_of module, CC0 license */
#define container_of(member_ptr, containing_type, member)		\
	 ((containing_type *)						\
	  ((char *)(member_ptr)						\
	   - container_off(containing_type, member))			\
	  + check_types_match(*(member_ptr), ((containing_type *)0)->member))

/* From ccan's container_of module, CC0 license */
#define container_off(containing_type, member)	\
		offsetof(containing_type, member)

/* From ccan's check_type module, CC0 license */
#define check_type(expr, type)			\
	((typeof(expr) *)0 != (type *)0)

/* From ccan's check_type module, CC0 license */
#define check_types_match(expr1, expr2)		\
	((typeof(expr1) *)0 != (typeof(expr2) *)0)

int mbox_set_mtd_data(struct mbox_context *context, const void *data,
		size_t len)
{
	struct mbox_test_context *arg;
	void *map;

	/* Sanity check */
	arg = container_of(context, struct mbox_test_context, context);
	if (&test != arg)
		return -1;

	if (len > test.context.mtd_info.size)
		return -2;

	map = mmap(NULL, test.context.mtd_info.size, PROT_WRITE, MAP_SHARED,
			test.flash.fd, 0);
	assert(map != MAP_FAILED);
	memcpy(map, data, len);
	munmap(map, test.context.mtd_info.size);

	return 0;
}

char *get_dev_mtd(void)
{
	return strdup(test.flash.path);
}
