// SPDX-License-Identifier: GPL-2.0+
/*
 * Chromium OS cros_ec driver - sandbox emulation
 *
 * Copyright (c) 2013 The Chromium OS Authors.
 */

#define LOG_CATEGORY UCLASS_CROS_EC

#include <common.h>
#include <cros_ec.h>
#include <dm.h>
#include <ec_commands.h>
#include <errno.h>
#include <hash.h>
#include <log.h>
#include <os.h>
#include <u-boot/sha256.h>
#include <spi.h>
#include <asm/malloc.h>
#include <asm/state.h>
#include <asm/sdl.h>
#include <asm/test.h>
#include <linux/input.h>

/*
 * Ultimately it shold be possible to connect an Chrome OS EC emulation
 * to U-Boot and remove all of this code. But this provides a test
 * environment for bringing up chromeos_sandbox and demonstrating its
 * utility.
 *
 * This emulation includes the following:
 *
 * 1. Emulation of the keyboard, by converting keypresses received from SDL
 * into key scan data, passed back from the EC as key scan messages. The
 * key layout is read from the device tree.
 *
 * 2. Emulation of vboot context - so this can be read/written as required.
 *
 * 3. Save/restore of EC state, so that the vboot context, flash memory
 * contents and current image can be preserved across boots. This is important
 * since the EC is supposed to continue running even if the AP resets.
 *
 * 4. Some event support, in particular allowing Escape to be pressed on boot
 * to enter recovery mode. The EC passes this to U-Boot through the normal
 * event message.
 *
 * 5. Flash read/write/erase support, so that software sync works. The
 * protect messages are supported but no protection is implemented.
 *
 * 6. Hashing of the EC image, again to support software sync.
 *
 * Other features can be added, although a better path is probably to link
 * the EC image in with U-Boot (Vic has demonstrated a prototype for this).
 */

#define KEYBOARD_ROWS	8
#define KEYBOARD_COLS	13

/* A single entry of the key matrix */
struct ec_keymatrix_entry {
	int row;	/* key matrix row */
	int col;	/* key matrix column */
	int keycode;	/* corresponding linux key code */
};

enum {
	VSTORE_SLOT_COUNT	= 4,
	PWM_CHANNEL_COUNT	= 4,
};

struct vstore_slot {
	bool locked;
	u8 data[EC_VSTORE_SLOT_SIZE];
};

struct ec_pwm_channel {
	uint duty;	/* not ns, EC_PWM_MAX_DUTY = 100% */
};

/**
 * struct ec_state - Information about the EC state
 *
 * @vbnv_context: Vboot context data stored by EC
 * @ec_config: FDT config information about the EC (e.g. flashmap)
 * @flash_data: Contents of flash memory
 * @flash_data_len: Size of flash memory
 * @current_image: Current image the EC is running
 * @matrix_count: Number of keys to decode in matrix
 * @matrix: Information about keyboard matrix
 * @keyscan: Current keyscan information (bit set for each row/column pressed)
 * @recovery_req: Keyboard recovery requested
 * @test_flags: Flags that control behaviour for tests
 * @slot_locked: Locked vstore slots (mask)
 * @pwm: Information per PWM channel
 */
struct ec_state {
	u8 vbnv_context[EC_VBNV_BLOCK_SIZE_V2];
	struct fdt_cros_ec ec_config;
	uint8_t *flash_data;
	int flash_data_len;
	enum ec_current_image current_image;
	int matrix_count;
	struct ec_keymatrix_entry *matrix;	/* the key matrix info */
	uint8_t keyscan[KEYBOARD_COLS];
	bool recovery_req;
	uint test_flags;
	struct vstore_slot slot[VSTORE_SLOT_COUNT];
	struct ec_pwm_channel pwm[PWM_CHANNEL_COUNT];
} s_state, *g_state;

/**
 * cros_ec_read_state() - read the sandbox EC state from the state file
 *
 * If data is available, then blob and node will provide access to it. If
 * not this function sets up an empty EC.
 *
 * @param blob: Pointer to device tree blob, or NULL if no data to read
 * @param node: Node offset to read from
 */
static int cros_ec_read_state(const void *blob, int node)
{
	struct ec_state *ec = &s_state;
	const char *prop;
	int len;

	/* Set everything to defaults */
	ec->current_image = EC_IMAGE_RO;
	if (!blob)
		return 0;

	/* Read the data if available */
	ec->current_image = fdtdec_get_int(blob, node, "current-image",
					   EC_IMAGE_RO);
	prop = fdt_getprop(blob, node, "vbnv-context", &len);
	if (prop && len == sizeof(ec->vbnv_context))
		memcpy(ec->vbnv_context, prop, len);

	prop = fdt_getprop(blob, node, "flash-data", &len);
	if (prop) {
		ec->flash_data_len = len;
		ec->flash_data = malloc(len);
		if (!ec->flash_data)
			return -ENOMEM;
		memcpy(ec->flash_data, prop, len);
		debug("%s: Loaded EC flash data size %#x\n", __func__, len);
	}

	return 0;
}

/**
 * cros_ec_write_state() - Write out our state to the state file
 *
 * The caller will ensure that there is a node ready for the state. The node
 * may already contain the old state, in which case it is overridden.
 *
 * @param blob: Device tree blob holding state
 * @param node: Node to write our state into
 */
static int cros_ec_write_state(void *blob, int node)
{
	struct ec_state *ec = g_state;

	if (!g_state)
		return 0;

	/* We are guaranteed enough space to write basic properties */
	fdt_setprop_u32(blob, node, "current-image", ec->current_image);
	fdt_setprop(blob, node, "vbnv-context", ec->vbnv_context,
		    sizeof(ec->vbnv_context));

	return state_setprop(node, "flash-data", ec->flash_data,
			     ec->ec_config.flash.length);
}

SANDBOX_STATE_IO(cros_ec, "google,cros-ec", cros_ec_read_state,
		 cros_ec_write_state);

/**
 * Return the number of bytes used in the specified image.
 *
 * This is the actual size of code+data in the image, as opposed to the
 * amount of space reserved in flash for that image. This code is similar to
 * that used by the real EC code base.
 *
 * @param ec	Current emulated EC state
 * @param entry	Flash map entry containing the image to check
 * @return actual image size in bytes, 0 if the image contains no content or
 * error.
 */
static int get_image_used(struct ec_state *ec, struct fmap_entry *entry)
{
	int size;

	/*
	 * Scan backwards looking for 0xea byte, which is by definition the
	 * last byte of the image.  See ec.lds.S for how this is inserted at
	 * the end of the image.
	 */
	for (size = entry->length - 1;
	     size > 0 && ec->flash_data[entry->offset + size] != 0xea;
	     size--)
		;

	return size ? size + 1 : 0;  /* 0xea byte IS part of the image */
}

/**
 * Read the key matrix from the device tree
 *
 * Keymap entries in the fdt take the form of 0xRRCCKKKK where
 * RR=Row CC=Column KKKK=Key Code
 *
 * @param ec	Current emulated EC state
 * @param node	Keyboard node of device tree containing keyscan information
 * @return 0 if ok, -1 on error
 */
static int keyscan_read_fdt_matrix(struct ec_state *ec, ofnode node)
{
	const u32 *cell;
	int upto;
	int len;

	cell = ofnode_get_property(node, "linux,keymap", &len);
	if (!cell)
		return log_msg_ret("prop", -EINVAL);
	ec->matrix_count = len / 4;
	ec->matrix = calloc(ec->matrix_count, sizeof(*ec->matrix));
	if (!ec->matrix) {
		return log_msg_ret("mem", -ENOMEM);
	}

	/* Now read the data */
	for (upto = 0; upto < ec->matrix_count; upto++) {
		struct ec_keymatrix_entry *matrix = &ec->matrix[upto];
		u32 word;

		word = fdt32_to_cpu(*cell++);
		matrix->row = word >> 24;
		matrix->col = (word >> 16) & 0xff;
		matrix->keycode = word & 0xffff;

		/* Hard-code some sanity limits for now */
		if (matrix->row >= KEYBOARD_ROWS ||
		    matrix->col >= KEYBOARD_COLS) {
			debug("%s: Matrix pos out of range (%d,%d)\n",
			      __func__, matrix->row, matrix->col);
			return log_msg_ret("matrix", -ERANGE);
		}
	}

	if (upto != ec->matrix_count) {
		return log_msg_ret("matrix", -E2BIG);
	}

	return 0;
}

/**
 * Return the next keyscan message contents
 *
 * @param ec	Current emulated EC state
 * @param scan	Place to put keyscan bytes for the keyscan message (must hold
 *		enough space for a full keyscan)
 * @return number of bytes of valid scan data
 */
static int cros_ec_keyscan(struct ec_state *ec, uint8_t *scan)
{
	const struct ec_keymatrix_entry *matrix;
	int bytes = KEYBOARD_COLS;
	int key[8];	/* allow up to 8 keys to be pressed at once */
	int count;
	int i;

	memset(ec->keyscan, '\0', bytes);
	count = sandbox_sdl_scan_keys(key, ARRAY_SIZE(key));

	/* Look up keycode in matrix */
	for (i = 0, matrix = ec->matrix; i < ec->matrix_count; i++, matrix++) {
		bool found;
		int j;

		for (found = false, j = 0; j < count; j++) {
			if (matrix->keycode == key[j])
				found = true;
		}

		if (found) {
			debug("%d: %d,%d\n", matrix->keycode, matrix->row,
			      matrix->col);
			ec->keyscan[matrix->col] |= 1 << matrix->row;
		}
	}

	memcpy(scan, ec->keyscan, bytes);
	return bytes;
}

/**
 * Process an emulated EC command
 *
 * @param ec		Current emulated EC state
 * @param req_hdr	Pointer to request header
 * @param req_data	Pointer to body of request
 * @param resp_hdr	Pointer to place to put response header
 * @param resp_data	Pointer to place to put response data, if any
 * @return length of response data, or 0 for no response data, or -1 on error
 */
static int process_cmd(struct ec_state *ec,
		       struct ec_host_request *req_hdr, const void *req_data,
		       struct ec_host_response *resp_hdr, void *resp_data)
{
	int len;

	/* TODO(sjg@chromium.org): Check checksums */
	debug("EC command %#0x\n", req_hdr->command);

	switch (req_hdr->command) {
	case EC_CMD_HELLO: {
		const struct ec_params_hello *req = req_data;
		struct ec_response_hello *resp = resp_data;

		resp->out_data = req->in_data + 0x01020304;
		if (ec->test_flags & CROSECT_BREAK_HELLO)
			resp->out_data++;
		len = sizeof(*resp);
		break;
	}
	case EC_CMD_GET_VERSION: {
		struct ec_response_get_version *resp = resp_data;

		strcpy(resp->version_string_ro, "sandbox_ro");
		strcpy(resp->version_string_rw, "sandbox_rw");
		resp->current_image = ec->current_image;
		debug("Current image %d\n", resp->current_image);
		len = sizeof(*resp);
		break;
	}
	case EC_CMD_VBNV_CONTEXT: {
		const struct ec_params_vbnvcontext *req = req_data;
		struct ec_response_vbnvcontext *resp = resp_data;

		switch (req->op) {
		case EC_VBNV_CONTEXT_OP_READ:
			memcpy(resp->block, ec->vbnv_context,
			       EC_VBNV_BLOCK_SIZE_V2);
			len = EC_VBNV_BLOCK_SIZE_V2;
			break;
		case EC_VBNV_CONTEXT_OP_WRITE:
			memcpy(ec->vbnv_context, req->block,
			       EC_VBNV_BLOCK_SIZE_V2);
			len = 0;
			break;
		default:
			printf("   ** Unknown vbnv_context command %#02x\n",
			       req->op);
			return -1;
		}
		break;
	}
	case EC_CMD_REBOOT_EC: {
		const struct ec_params_reboot_ec *req = req_data;

		printf("Request reboot type %d\n", req->cmd);
		switch (req->cmd) {
		case EC_REBOOT_DISABLE_JUMP:
			len = 0;
			break;
		case EC_REBOOT_JUMP_RW:
			ec->current_image = EC_IMAGE_RW;
			len = 0;
			break;
		default:
			puts("   ** Unknown type");
			return -1;
		}
		break;
	}
	case EC_CMD_HOST_EVENT_GET_B: {
		struct ec_response_host_event_mask *resp = resp_data;

		resp->mask = 0;
		if (ec->recovery_req) {
			resp->mask |= EC_HOST_EVENT_MASK(
					EC_HOST_EVENT_KEYBOARD_RECOVERY);
		}
		if (ec->test_flags & CROSECT_LID_OPEN)
			resp->mask |=
				EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN);
		len = sizeof(*resp);
		break;
	}
	case EC_CMD_HOST_EVENT_CLEAR_B: {
		const struct ec_params_host_event_mask *req = req_data;

		if (req->mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN))
			ec->test_flags &= ~CROSECT_LID_OPEN;
		len = 0;
		break;
		}
	case EC_CMD_VBOOT_HASH: {
		const struct ec_params_vboot_hash *req = req_data;
		struct ec_response_vboot_hash *resp = resp_data;
		struct fmap_entry *entry;
		int ret, size;

		entry = &ec->ec_config.region[EC_FLASH_REGION_ACTIVE];

		switch (req->cmd) {
		case EC_VBOOT_HASH_RECALC:
		case EC_VBOOT_HASH_GET:
			size = SHA256_SUM_LEN;
			len = get_image_used(ec, entry);
			ret = hash_block("sha256",
					 ec->flash_data + entry->offset,
					 len, resp->hash_digest, &size);
			if (ret) {
				printf("   ** hash_block() failed\n");
				return -1;
			}
			resp->status = EC_VBOOT_HASH_STATUS_DONE;
			resp->hash_type = EC_VBOOT_HASH_TYPE_SHA256;
			resp->digest_size = size;
			resp->reserved0 = 0;
			resp->offset = entry->offset;
			resp->size = len;
			len = sizeof(*resp);
			break;
		default:
			printf("   ** EC_CMD_VBOOT_HASH: Unknown command %d\n",
			       req->cmd);
			return -1;
		}
		break;
	}
	case EC_CMD_FLASH_PROTECT: {
		const struct ec_params_flash_protect *req = req_data;
		struct ec_response_flash_protect *resp = resp_data;
		uint32_t expect = EC_FLASH_PROTECT_ALL_NOW |
				EC_FLASH_PROTECT_ALL_AT_BOOT;

		printf("mask=%#x, flags=%#x\n", req->mask, req->flags);
		if (req->flags == expect || req->flags == 0) {
			resp->flags = req->flags ? EC_FLASH_PROTECT_ALL_NOW :
								0;
			resp->valid_flags = EC_FLASH_PROTECT_ALL_NOW;
			resp->writable_flags = 0;
			len = sizeof(*resp);
		} else {
			puts("   ** unexpected flash protect request\n");
			return -1;
		}
		break;
	}
	case EC_CMD_FLASH_REGION_INFO: {
		const struct ec_params_flash_region_info *req = req_data;
		struct ec_response_flash_region_info *resp = resp_data;
		struct fmap_entry *entry;

		switch (req->region) {
		case EC_FLASH_REGION_RO:
		case EC_FLASH_REGION_ACTIVE:
		case EC_FLASH_REGION_WP_RO:
			entry = &ec->ec_config.region[req->region];
			resp->offset = entry->offset;
			resp->size = entry->length;
			len = sizeof(*resp);
			printf("EC flash region %d: offset=%#x, size=%#x\n",
			       req->region, resp->offset, resp->size);
			break;
		default:
			printf("** Unknown flash region %d\n", req->region);
			return -1;
		}
		break;
	}
	case EC_CMD_FLASH_ERASE: {
		const struct ec_params_flash_erase *req = req_data;

		memset(ec->flash_data + req->offset,
		       ec->ec_config.flash_erase_value,
		       req->size);
		len = 0;
		break;
	}
	case EC_CMD_FLASH_WRITE: {
		const struct ec_params_flash_write *req = req_data;

		memcpy(ec->flash_data + req->offset, req + 1, req->size);
		len = 0;
		break;
	}
	case EC_CMD_MKBP_STATE:
		len = cros_ec_keyscan(ec, resp_data);
		break;
	case EC_CMD_GET_NEXT_EVENT: {
		struct ec_response_get_next_event *resp = resp_data;

		resp->event_type = EC_MKBP_EVENT_KEY_MATRIX;
		cros_ec_keyscan(ec, resp->data.key_matrix);
		len = sizeof(*resp);
		break;
	}
	case EC_CMD_GET_SKU_ID: {
		struct ec_sku_id_info *resp = resp_data;

		resp->sku_id = 1234;
		len = sizeof(*resp);
		break;
	}
	case EC_CMD_GET_FEATURES: {
		struct ec_response_get_features *resp = resp_data;

		resp->flags[0] = EC_FEATURE_MASK_0(EC_FEATURE_FLASH) |
			EC_FEATURE_MASK_0(EC_FEATURE_I2C) |
			EC_FEATURE_MASK_0(EC_FEATURE_VSTORE);
		resp->flags[1] =
			EC_FEATURE_MASK_1(EC_FEATURE_UNIFIED_WAKE_MASKS) |
			EC_FEATURE_MASK_1(EC_FEATURE_ISH);
		len = sizeof(*resp);
		break;
	}
	case EC_CMD_VSTORE_INFO: {
		struct ec_response_vstore_info *resp = resp_data;
		int i;

		resp->slot_count = VSTORE_SLOT_COUNT;
		resp->slot_locked = 0;
		for (i = 0; i < VSTORE_SLOT_COUNT; i++) {
			if (ec->slot[i].locked)
				resp->slot_locked |= 1 << i;
		}
		len = sizeof(*resp);
		break;
	};
	case EC_CMD_VSTORE_WRITE: {
		const struct ec_params_vstore_write *req = req_data;
		struct vstore_slot *slot;

		if (req->slot >= EC_VSTORE_SLOT_MAX)
			return -EINVAL;
		slot = &ec->slot[req->slot];
		slot->locked = true;
		memcpy(slot->data, req->data, EC_VSTORE_SLOT_SIZE);
		len = 0;
		break;
	}
	case EC_CMD_VSTORE_READ: {
		const struct ec_params_vstore_read *req = req_data;
		struct ec_response_vstore_read *resp = resp_data;
		struct vstore_slot *slot;

		if (req->slot >= EC_VSTORE_SLOT_MAX)
			return -EINVAL;
		slot = &ec->slot[req->slot];
		memcpy(resp->data, slot->data, EC_VSTORE_SLOT_SIZE);
		len = sizeof(*resp);
		break;
	}
	case EC_CMD_PWM_GET_DUTY: {
		const struct ec_params_pwm_get_duty *req = req_data;
		struct ec_response_pwm_get_duty *resp = resp_data;
		struct ec_pwm_channel *pwm;

		if (req->pwm_type != EC_PWM_TYPE_GENERIC)
			return -EINVAL;
		if (req->index >= PWM_CHANNEL_COUNT)
			return -EINVAL;
		pwm = &ec->pwm[req->index];
		resp->duty = pwm->duty;
		len = sizeof(*resp);
		break;
	}
	case EC_CMD_PWM_SET_DUTY: {
		const struct ec_params_pwm_set_duty *req = req_data;
		struct ec_pwm_channel *pwm;

		if (req->pwm_type != EC_PWM_TYPE_GENERIC)
			return -EINVAL;
		if (req->index >= PWM_CHANNEL_COUNT)
			return -EINVAL;
		pwm = &ec->pwm[req->index];
		pwm->duty = req->duty;
		len = 0;
		break;
	}
	default:
		printf("   ** Unknown EC command %#02x\n", req_hdr->command);
		return -1;
	}

	return len;
}

int cros_ec_sandbox_packet(struct udevice *udev, int out_bytes, int in_bytes)
{
	struct cros_ec_dev *dev = dev_get_uclass_priv(udev);
	struct ec_state *ec = dev_get_priv(dev->dev);
	struct ec_host_request *req_hdr = (struct ec_host_request *)dev->dout;
	const void *req_data = req_hdr + 1;
	struct ec_host_response *resp_hdr = (struct ec_host_response *)dev->din;
	void *resp_data = resp_hdr + 1;
	int len;

	len = process_cmd(ec, req_hdr, req_data, resp_hdr, resp_data);
	if (len < 0)
		return len;

	resp_hdr->struct_version = 3;
	resp_hdr->result = EC_RES_SUCCESS;
	resp_hdr->data_len = len;
	resp_hdr->reserved = 0;
	len += sizeof(*resp_hdr);
	resp_hdr->checksum = 0;
	resp_hdr->checksum = (uint8_t)
		-cros_ec_calc_checksum((const uint8_t *)resp_hdr, len);

	return in_bytes;
}

void cros_ec_check_keyboard(struct udevice *dev)
{
	struct ec_state *ec = dev_get_priv(dev);
	ulong start;

	printf("\nPress keys for EC to detect on reset (ESC=recovery)...");
	start = get_timer(0);
	while (get_timer(start) < 2000) {
		if (tstc()) {
			int ch = getchar();

			if (ch == 0x1b) {
				ec->recovery_req = true;
				printf("EC requests recovery");
			}
		}
	}
	putc('\n');
}

/* Return the byte of EC switch states */
static int cros_ec_sandbox_get_switches(struct udevice *dev)
{
	struct ec_state *ec = dev_get_priv(dev);

	return ec->test_flags & CROSECT_LID_OPEN ? EC_SWITCH_LID_OPEN : 0;
}

void sandbox_cros_ec_set_test_flags(struct udevice *dev, uint flags)
{
	struct ec_state *ec = dev_get_priv(dev);

	ec->test_flags = flags;
}

int sandbox_cros_ec_get_pwm_duty(struct udevice *dev, uint index, uint *duty)
{
	struct ec_state *ec = dev_get_priv(dev);
	struct ec_pwm_channel *pwm;

	if (index >= PWM_CHANNEL_COUNT)
		return -ENOSPC;
	pwm = &ec->pwm[index];
	*duty = pwm->duty;

	return 0;
}

int cros_ec_probe(struct udevice *dev)
{
	struct ec_state *ec = dev_get_priv(dev);
	struct cros_ec_dev *cdev = dev_get_uclass_priv(dev);
	struct udevice *keyb_dev;
	ofnode node;
	int err;

	memcpy(ec, &s_state, sizeof(*ec));
	err = cros_ec_decode_ec_flash(dev, &ec->ec_config);
	if (err) {
		debug("%s: Cannot device EC flash\n", __func__);
		return err;
	}

	node = ofnode_null();
	for (device_find_first_child(dev, &keyb_dev);
	     keyb_dev;
	     device_find_next_child(&keyb_dev)) {
		if (device_get_uclass_id(keyb_dev) == UCLASS_KEYBOARD) {
			node = dev_ofnode(keyb_dev);
			break;
		}
	}
	if (!ofnode_valid(node)) {
		debug("%s: No cros_ec keyboard found\n", __func__);
	} else if (keyscan_read_fdt_matrix(ec, node)) {
		debug("%s: Could not read key matrix\n", __func__);
		return -1;
	}

	/* If we loaded EC data, check that the length matches */
	if (ec->flash_data &&
	    ec->flash_data_len != ec->ec_config.flash.length) {
		printf("EC data length is %x, expected %x, discarding data\n",
		       ec->flash_data_len, ec->ec_config.flash.length);
		free(ec->flash_data);
		ec->flash_data = NULL;
	}

	/* Otherwise allocate the memory */
	if (!ec->flash_data) {
		ec->flash_data_len = ec->ec_config.flash.length;
		ec->flash_data = malloc(ec->flash_data_len);
		if (!ec->flash_data)
			return -ENOMEM;
	}

	cdev->dev = dev;
	g_state = ec;
	return cros_ec_register(dev);
}

struct dm_cros_ec_ops cros_ec_ops = {
	.packet = cros_ec_sandbox_packet,
	.get_switches = cros_ec_sandbox_get_switches,
};

static const struct udevice_id cros_ec_ids[] = {
	{ .compatible = "google,cros-ec-sandbox" },
	{ }
};

U_BOOT_DRIVER(google_cros_ec_sandbox) = {
	.name		= "google_cros_ec_sandbox",
	.id		= UCLASS_CROS_EC,
	.of_match	= cros_ec_ids,
	.probe		= cros_ec_probe,
	.priv_auto	= sizeof(struct ec_state),
	.ops		= &cros_ec_ops,
};
