Exemplo n.º 1
0
/**
 * Perform a flash read or write command
 *
 * @param dev		CROS-EC device to read/write
 * @param is_write	1 do to a write, 0 to do a read
 * @param argc		Number of arguments
 * @param argv		Arguments (2 is region, 3 is address)
 * @return 0 for ok, 1 for a usage error or -ve for ec command error
 *	(negative EC_RES_...)
 */
static int do_read_write(struct cros_ec_dev *dev, int is_write, int argc,
			 char * const argv[])
{
	uint32_t offset, size = -1U, region_size;
	unsigned long addr;
	char *endp;
	int region;
	int ret;

	region = cros_ec_decode_region(argc - 2, argv + 2);
	if (region == -1)
		return 1;
	if (argc < 4)
		return 1;
	addr = simple_strtoul(argv[3], &endp, 16);
	if (*argv[3] == 0 || *endp != 0)
		return 1;
	if (argc > 4) {
		size = simple_strtoul(argv[4], &endp, 16);
		if (*argv[4] == 0 || *endp != 0)
			return 1;
	}

	ret = cros_ec_flash_offset(dev, region, &offset, &region_size);
	if (ret) {
		debug("%s: Could not read region info\n", __func__);
		return ret;
	}
	if (size == -1U)
		size = region_size;

	ret = is_write ?
		cros_ec_flash_write(dev, (uint8_t *)addr, offset, size) :
		cros_ec_flash_read(dev, (uint8_t *)addr, offset, size);
	if (ret) {
		debug("%s: Could not %s region\n", __func__,
		      is_write ? "write" : "read");
		return ret;
	}

	return 0;
}
Exemplo n.º 2
0
int cros_ec_flash_update_rw(struct udevice *dev, const uint8_t *image,
			    int image_size)
{
	uint32_t rw_offset, rw_size;
	int ret;

	if (cros_ec_flash_offset(dev, EC_FLASH_REGION_ACTIVE, &rw_offset,
		&rw_size))
		return -1;
	if (image_size > (int)rw_size)
		return -1;

	/* Invalidate the existing hash, just in case the AP reboots
	 * unexpectedly during the update. If that happened, the EC RW firmware
	 * would be invalid, but the EC would still have the original hash.
	 */
	ret = cros_ec_invalidate_hash(dev);
	if (ret)
		return ret;

	/*
	 * Erase the entire RW section, so that the EC doesn't see any garbage
	 * past the new image if it's smaller than the current image.
	 *
	 * TODO: could optimize this to erase just the current image, since
	 * presumably everything past that is 0xff's.  But would still need to
	 * round up to the nearest multiple of erase size.
	 */
	ret = cros_ec_flash_erase(dev, rw_offset, rw_size);
	if (ret)
		return ret;

	/* Write the image */
	ret = cros_ec_flash_write(dev, image, rw_offset, image_size);
	if (ret)
		return ret;

	return 0;
}