/**
 * Get the versions of the command supported by the EC.
 *
 * @param cmd		Command
 * @param pmask		Destination for version mask; will be set to 0 on
 *			error.
 * @return 0 if success, <0 if error
 */
int ec_get_cmd_versions(int cmd, uint32_t *pmask)
{
	struct ec_params_get_cmd_versions_v1 pver_v1;
	struct ec_params_get_cmd_versions pver;
	struct ec_response_get_cmd_versions rver;
	int rv;

	*pmask = 0;

	pver_v1.cmd = cmd;
	rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 1, &pver_v1, sizeof(pver_v1),
			&rver, sizeof(rver));

	if (rv < 0) {
		pver.cmd = cmd;
		rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 0, &pver, sizeof(pver),
				&rver, sizeof(rver));
	}

	if (rv < 0)
		return rv;

	*pmask = rver.version_mask;
	return 0;
}
Пример #2
0
static int fake_readmem(int offset, int bytes, void *dest)
{
	struct ec_params_read_memmap p;
	int c;
	char *buf;

	p.offset = offset;

	if (bytes) {
		p.size = bytes;
		c = ec_command(EC_CMD_READ_MEMMAP, 0, &p, sizeof(p),
			       dest, p.size);
		if (c < 0)
			return c;
		return p.size;
	}

	p.size = EC_MEMMAP_TEXT_MAX;

	c = ec_command(EC_CMD_READ_MEMMAP, 0, &p, sizeof(p), dest, p.size);
	if (c < 0)
		return c;

	buf = dest;
	for (c = 0; c < EC_MEMMAP_TEXT_MAX; c++) {
		if (buf[c] == 0)
			return c;
	}

	buf[EC_MEMMAP_TEXT_MAX - 1] = 0;
	return EC_MEMMAP_TEXT_MAX - 1;
}
Пример #3
0
int cros_ec_tunnel_i2c_protect(CrosECTunnelI2c *bus)
{
	struct ec_params_i2c_passthru_protect params = {
		.subcmd = EC_CMD_I2C_PASSTHRU_PROTECT_ENABLE,
		.port = bus->remote_bus
	};
	int result;

	result = ec_command(bus->ec, EC_CMD_I2C_PASSTHRU_PROTECT, 0,
			    &params, sizeof(params),
			    NULL, 0);

	if (result < 0)
		return result;

	return 0;
}

int cros_ec_tunnel_i2c_protect_status(CrosECTunnelI2c *bus, int *status)
{
	struct ec_params_i2c_passthru_protect params = {
		.subcmd = EC_CMD_I2C_PASSTHRU_PROTECT_STATUS,
		.port = bus->remote_bus
	};
	struct ec_response_i2c_passthru_protect response;
	int result;

	result = ec_command(bus->ec, EC_CMD_I2C_PASSTHRU_PROTECT, 0,
			    &params, sizeof(params),
			    &response, sizeof(response));

	if (result < 0)
		return result;

	if (result < sizeof(response))
		return -1;

	*status = response.status;

	return 0;
}

CrosECTunnelI2c *new_cros_ec_tunnel_i2c(CrosEc *ec,
					uint16_t remote_bus) {
	CrosECTunnelI2c *bus = xzalloc(sizeof(*bus));

	assert(ec);

	bus->ops.transfer = &i2c_transfer;
	bus->ec = ec;
	bus->remote_bus = remote_bus;

	return bus;
}
int ec_flash_write(const uint8_t *buf, int offset, int size)
{
	struct ec_params_flash_write *p =
		(struct ec_params_flash_write *)ec_outbuf;
	struct ec_response_flash_info info;
	int pdata_max_size = (int)(ec_max_outsize - sizeof(*p));
	int step;
	int rv;
	int i;

	/*
	 * Determine whether we can use version 1 of the command with more
	 * data, or only version 0.
	 */
	if (!ec_cmd_version_supported(EC_CMD_FLASH_WRITE, EC_VER_FLASH_WRITE))
		pdata_max_size = EC_FLASH_WRITE_VER0_SIZE;

	/*
	 * Determine step size.  This must be a multiple of the write block
	 * size, and must also fit into the host parameter buffer.
	 */
	rv = ec_command(EC_CMD_FLASH_INFO, 0, NULL, 0, &info, sizeof(info));
	if (rv < 0)
		return rv;

	step = (pdata_max_size / info.write_block_size) * info.write_block_size;

	if (!step) {
		fprintf(stderr, "Write block size %d > max param size %d\n",
			info.write_block_size, pdata_max_size);
		return -1;
	}

	/* Write data in chunks */
	printf("Write size %d...\n", step);

	for (i = 0; i < size; i += step) {
		p->offset = offset + i;
		p->size = MIN(size - i, step);
		memcpy(p + 1, buf + i, p->size);
		rv = ec_command(EC_CMD_FLASH_WRITE, 0, p, sizeof(*p) + p->size,
				NULL, 0);
		if (rv < 0) {
			fprintf(stderr, "Write error at offset %d\n", i);
			return rv;
		}
	}

	return 0;
}
Пример #5
0
static int get_info(struct sb_fw_update_info *info)
{
	int rv = EC_RES_SUCCESS;
	int cnt = 0;

	struct ec_params_sb_fw_update *param =
		(struct ec_params_sb_fw_update *)ec_outbuf;

	struct ec_response_sb_fw_update *resp =
		(struct ec_response_sb_fw_update *)ec_inbuf;

	param->hdr.subcmd = EC_SB_FW_UPDATE_INFO;
	do {
		usleep(SB_FW_UPDATE_DEFAULT_DELAY);
		rv = ec_command(EC_CMD_SB_FW_UPDATE, 0,
			param, sizeof(struct ec_sb_fw_update_header),
			resp, SB_FW_UPDATE_CMD_INFO_SIZE);
	} while ((rv < 0) && (cnt++ < SB_FW_UPDATE_DEFAULT_RETRY_CNT));

	if (rv < 0) {
		memset(info, 0, SB_FW_UPDATE_CMD_INFO_SIZE);
		return -EC_RES_ERROR;
	}

	memcpy(info, resp->info.data, SB_FW_UPDATE_CMD_INFO_SIZE);
	return EC_RES_SUCCESS;
}
Пример #6
0
int cros_ec_read_limit_power(struct udevice *dev, int *limit_powerp)
{
	struct ec_params_charge_state p;
	struct ec_response_charge_state r;
	int ret;

	p.cmd = CHARGE_STATE_CMD_GET_PARAM;
	p.get_param.param = CS_PARAM_LIMIT_POWER;
	ret = ec_command(dev, EC_CMD_CHARGE_STATE, 0, &p, sizeof(p),
			 &r, sizeof(r));

	/*
	 * If our EC doesn't support the LIMIT_POWER parameter, assume that
	 * LIMIT_POWER is not requested.
	 */
	if (ret == -EC_RES_INVALID_PARAM || ret == -EC_RES_INVALID_COMMAND) {
		log_warning("PARAM_LIMIT_POWER not supported by EC\n");
		return -ENOSYS;
	}

	if (ret != sizeof(r.get_param))
		return -EINVAL;

	*limit_powerp = r.get_param.value;
	return 0;
}
Пример #7
0
int cros_ec_scan_keyboard(struct cros_ec_dev *dev, struct mbkp_keyscan *scan)
{
	if (ec_command(dev, EC_CMD_MKBP_STATE, 0, NULL, 0, scan,
		       sizeof(scan->data)) != sizeof(scan->data))
		return -1;

	return 0;
}
Пример #8
0
int cros_ec_info(struct cros_ec_dev *dev, struct ec_response_mkbp_info *info)
{
	if (ec_command(dev, EC_CMD_MKBP_INFO, 0, NULL, 0, info,
		       sizeof(*info)) != sizeof(*info))
		return -1;

	return 0;
}
int ec_flash_erase(int offset, int size)
{
	struct ec_params_flash_erase p;

	p.offset = offset;
	p.size = size;

	return ec_command(EC_CMD_FLASH_ERASE, 0, &p, sizeof(p), NULL, 0);
}
Пример #10
0
int cros_ec_read_hash(struct udevice *dev, uint hash_offset,
		      struct ec_response_vboot_hash *hash)
{
	struct ec_params_vboot_hash p;
	int rv;

	p.cmd = EC_VBOOT_HASH_GET;
	p.offset = hash_offset;
	if (ec_command(dev, EC_CMD_VBOOT_HASH, 0, &p, sizeof(p),
		       hash, sizeof(*hash)) < 0)
		return -1;

	/* If the EC is busy calculating the hash, fidget until it's done. */
	rv = cros_ec_wait_on_hash_done(dev, hash);
	if (rv)
		return rv;

	/* If the hash is valid, we're done. Otherwise, we have to kick it off
	 * again and wait for it to complete. Note that we explicitly assume
	 * that hashing zero bytes is always wrong, even though that would
	 * produce a valid hash value. */
	if (hash->status == EC_VBOOT_HASH_STATUS_DONE && hash->size)
		return 0;

	debug("%s: No valid hash (status=%d size=%d). Compute one...\n",
	      __func__, hash->status, hash->size);

	p.cmd = EC_VBOOT_HASH_START;
	p.hash_type = EC_VBOOT_HASH_TYPE_SHA256;
	p.nonce_size = 0;
	p.offset = hash_offset;

	if (ec_command(dev, EC_CMD_VBOOT_HASH, 0, &p, sizeof(p),
		       hash, sizeof(*hash)) < 0)
		return -1;

	rv = cros_ec_wait_on_hash_done(dev, hash);
	if (rv)
		return rv;

	debug("%s: hash done\n", __func__);

	return 0;
}
Пример #11
0
int cros_ec_entering_mode(struct udevice *dev, int mode)
{
	int rc;

	rc = ec_command(dev, EC_CMD_ENTERING_MODE, 0, &mode, sizeof(mode),
			NULL, 0);
	if (rc)
		return -1;
	return 0;
}
Пример #12
0
int CROSKBLIGHTGetBacklight() {
	struct ec_response_pwm_get_keyboard_backlight r;

	int rv;
	rv = ec_command(EC_CMD_PWM_GET_KEYBOARD_BACKLIGHT, 0,
		NULL, 0, &r, sizeof(r));
	if (rv < 0)
		return rv;

	return r.percent;
}
Пример #13
0
/**
 * Read a single block from the flash
 *
 * Read a block of data from the EC flash. The size must not exceed the flash
 * write block size which you can obtain from cros_ec_flash_write_burst_size().
 *
 * The offset starts at 0. You can obtain the region information from
 * cros_ec_flash_offset() to find out where to read for a particular region.
 *
 * @param dev		CROS-EC device
 * @param data		Pointer to data buffer to read into
 * @param offset	Offset within flash to read from
 * @param size		Number of bytes to read
 * @return 0 if ok, -1 on error
 */
static int cros_ec_flash_read_block(struct cros_ec_dev *dev, uint8_t *data,
				 uint32_t offset, uint32_t size)
{
	struct ec_params_flash_read p;

	p.offset = offset;
	p.size = size;

	return ec_command(dev, EC_CMD_FLASH_READ, 0,
			  &p, sizeof(p), data, size) >= 0 ? 0 : -1;
}
Пример #14
0
/**
 * Read back flash parameters
 *
 * This function reads back parameters of the flash as reported by the EC
 *
 * @param dev  Pointer to device
 * @param info Pointer to output flash info struct
 */
int cros_ec_read_flashinfo(struct udevice *dev,
			   struct ec_response_flash_info *info)
{
	int ret;

	ret = ec_command(dev, EC_CMD_FLASH_INFO, 0,
			 NULL, 0, info, sizeof(*info));
	if (ret < 0)
		return ret;

	return ret < sizeof(*info) ? -1 : 0;
}
Пример #15
0
int cros_ec_battery_cutoff(struct udevice *dev, uint8_t flags)
{
	struct ec_params_battery_cutoff p;
	int len;

	p.flags = flags;
	len = ec_command(dev, EC_CMD_BATTERY_CUT_OFF, 1, &p, sizeof(p),
			 NULL, 0);

	if (len < 0)
		return -1;
	return 0;
}
Пример #16
0
int CROSKBLIGHTSetBacklight(int percent) {
	struct ec_params_pwm_set_keyboard_backlight p;
	p.percent = percent;
	char *e;
	int rv;

	rv = ec_command(EC_CMD_PWM_SET_KEYBOARD_BACKLIGHT, 0,
		&p, sizeof(p), NULL, 0);
	if (rv < 0)
		return rv;

	return 0;
}
Пример #17
0
int cros_ec_set_event_mask(struct udevice *dev, uint type, uint32_t mask)
{
	struct ec_params_host_event_mask req;
	int ret;

	req.mask = mask;

	ret = ec_command(dev, type, 0, &req, sizeof(req), NULL, 0);
	if (ret < 0)
		return ret;

	return 0;
}
Пример #18
0
int cros_ec_config_powerbtn(struct udevice *dev, uint32_t flags)
{
	struct ec_params_config_power_button params;
	int ret;

	params.flags = flags;
	ret = ec_command(dev, EC_CMD_CONFIG_POWER_BUTTON, 0,
			 &params, sizeof(params), NULL, 0);
	if (ret < 0)
		return ret;

	return 0;
}
Пример #19
0
int cros_ec_check_feature(struct udevice *dev, int feature)
{
	struct ec_response_get_features r;
	int rv;

	rv = ec_command(dev, EC_CMD_GET_FEATURES, 0, &r, sizeof(r), NULL, 0);
	if (rv)
		return rv;

	if (feature >= 8 * sizeof(r.flags))
		return -1;

	return r.flags[feature / 32] & EC_FEATURE_MASK_0(feature);
}
Пример #20
0
int cros_ec_read_vbnvcontext(struct cros_ec_dev *dev, uint8_t *block)
{
	struct ec_params_vbnvcontext p;
	int len;

	p.op = EC_VBNV_CONTEXT_OP_READ;

	len = ec_command(dev, EC_CMD_VBNV_CONTEXT, EC_VER_VBNV_CONTEXT,
			&p, sizeof(p), block, EC_VBNV_BLOCK_SIZE);
	if (len < EC_VBNV_BLOCK_SIZE)
		return -1;

	return 0;
}
Пример #21
0
int cros_ec_get_event_mask(struct udevice *dev, uint type, uint32_t *mask)
{
	struct ec_response_host_event_mask rsp;
	int ret;

	ret = ec_command(dev, type, 0, NULL, 0, &rsp, sizeof(rsp));
	if (ret < 0)
		return ret;
	else if (ret != sizeof(rsp))
		return -EINVAL;

	*mask = rsp.mask;

	return 0;
}
Пример #22
0
int cros_ec_flash_protect(struct cros_ec_dev *dev,
		       uint32_t set_mask, uint32_t set_flags,
		       struct ec_response_flash_protect *resp)
{
	struct ec_params_flash_protect params;

	params.mask = set_mask;
	params.flags = set_flags;

	if (ec_command(dev, EC_CMD_FLASH_PROTECT, EC_VER_FLASH_PROTECT,
		       &params, sizeof(params),
		       resp, sizeof(*resp)) != sizeof(*resp))
		return -1;

	return 0;
}
Пример #23
0
void
ckb_ec_intr(void *arg)
{
	struct ckb_softc *sc;

	sc = arg;

	if (sc->sc_flags & CKB_FLAG_POLLING)
		return;

	ec_command(EC_CMD_MKBP_STATE, sc->scan, sc->cols,
	    sc->scan, sc->cols);

	(sc->sc_kbd.kb_callback.kc_func) (&sc->sc_kbd, KBDIO_KEYINPUT,
	    sc->sc_kbd.kb_callback.kc_arg);
};
Пример #24
0
static int send_subcmd(int subcmd)
{
	int rv = EC_RES_SUCCESS;

	struct ec_params_sb_fw_update *param =
		(struct ec_params_sb_fw_update *)ec_outbuf;

	param->hdr.subcmd = subcmd;
	rv = ec_command(EC_CMD_SB_FW_UPDATE, 0,
		param, sizeof(struct ec_sb_fw_update_header), NULL, 0);
	if (rv < 0) {
		printf("Firmware Update subcmd:%d Error\n", subcmd);
		return -EC_RES_ERROR;
	}
	return EC_RES_SUCCESS;
}
Пример #25
0
int cros_ec_read_nvdata(struct udevice *dev, uint8_t *block, int size)
{
	struct ec_params_vbnvcontext p;
	int len;

	if (size != EC_VBNV_BLOCK_SIZE && size != EC_VBNV_BLOCK_SIZE_V2)
		return -EINVAL;

	p.op = EC_VBNV_CONTEXT_OP_READ;

	len = ec_command(dev, EC_CMD_VBNV_CONTEXT, EC_VER_VBNV_CONTEXT,
			 &p, sizeof(uint32_t) + size, block, size);
	if (len != size) {
		log_err("Expected %d bytes, got %d\n", size, len);
		return -EIO;
	}

	return 0;
}
Пример #26
0
static int write_block(struct fw_update_ctrl *fw_update,
			int offset, int bsize)
{
	int rv;

	struct ec_params_sb_fw_update *param =
		(struct ec_params_sb_fw_update *)ec_outbuf;

	memcpy(param->write.data, fw_update->ptr+offset, bsize);

	param->hdr.subcmd = EC_SB_FW_UPDATE_WRITE;
	rv = ec_command(EC_CMD_SB_FW_UPDATE, 0,
		param, sizeof(struct ec_params_sb_fw_update), NULL, 0);
	if (rv < 0) {
		printf("Firmware Update Write Error ptr:%p offset@%x\n",
			fw_update->ptr, offset);
		return -EC_RES_ERROR;
	}
	return EC_RES_SUCCESS;
}
Пример #27
0
/**
 * Run verification on a slot
 *
 * @param me     CrosEc instance
 * @param region Region to run verification on
 * @return 0 if success or not applicable. Non-zero if verification failed.
 */
int cros_ec_efs_verify(struct udevice *dev, enum ec_flash_region region)
{
	struct ec_params_efs_verify p;
	int rv;

	log_info("EFS: EC is verifying updated image...\n");
	p.region = region;

	rv = ec_command(dev, EC_CMD_EFS_VERIFY, 0, &p, sizeof(p), NULL, 0);
	if (rv >= 0) {
		log_info("EFS: Verification success\n");
		return 0;
	}
	if (rv == -EC_RES_INVALID_COMMAND) {
		log_info("EFS: EC doesn't support EFS_VERIFY command\n");
		return 0;
	}
	log_info("EFS: Verification failed\n");

	return rv;
}
Пример #28
0
int ec_flash_read(uint8_t *buf, int offset, int size)
{
	struct ec_params_flash_read p;
	int rv;
	int i;

	/* Read data in chunks */
	for (i = 0; i < size; i += ec_max_insize) {
		p.offset = offset + i;
		p.size = MIN(size - i, ec_max_insize);
		rv = ec_command(EC_CMD_FLASH_READ, 0,
				&p, sizeof(p), ec_inbuf, p.size);
		if (rv < 0) {
			fprintf(stderr, "Read error at offset %d\n", i);
			return rv;
		}
		memcpy(buf + i, ec_inbuf, p.size);
	}

	return 0;
}
Пример #29
0
static int cros_ec_wait_on_hash_done(struct cros_ec_dev *dev,
				  struct ec_response_vboot_hash *hash)
{
	struct ec_params_vboot_hash p;
	ulong start;

	start = get_timer(0);
	while (hash->status == EC_VBOOT_HASH_STATUS_BUSY) {
		mdelay(50);	/* Insert some reasonable delay */

		p.cmd = EC_VBOOT_HASH_GET;
		if (ec_command(dev, EC_CMD_VBOOT_HASH, 0, &p, sizeof(p),
		       hash, sizeof(*hash)) < 0)
			return -1;

		if (get_timer(start) > CROS_EC_CMD_HASH_TIMEOUT_MS) {
			debug("%s: EC_VBOOT_HASH_GET timeout\n", __func__);
			return -EC_RES_TIMEOUT;
		}
	}
	return 0;
}
Пример #30
0
static int cros_ec_handle_non_uhepi_cmd(struct udevice *dev, uint hcmd,
					uint action, uint64_t *value)
{
	int ret = -1;
	struct ec_params_host_event_mask req;
	struct ec_response_host_event_mask rsp;

	if (hcmd == INVALID_HCMD)
		return ret;

	if (action != EC_HOST_EVENT_GET)
		req.mask = (uint32_t)*value;
	else
		*value = 0;

	ret = ec_command(dev, hcmd, 0, &req, sizeof(req), &rsp, sizeof(rsp));
	if (action != EC_HOST_EVENT_GET)
		return ret;
	if (ret == 0)
		*value = rsp.mask;

	return ret;
}