// 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 <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 <time.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
 *
 * @valid: true if this struct contains valid state data
 * @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 {
	bool valid;
	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);
	}
	ec->valid = true;

	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;
	}
	debug(" - EC command %#0x, result %d\n", req_hdr->command, len);

	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;

	if (s_state.valid)
		memcpy(ec, &s_state, sizeof(*ec));
	else
		ec->current_image = EC_IMAGE_RO;
	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,
};
