mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
Add common interface to EC flash commands
ectool and burn_my_ec need to use the same lower-level interface to the EC flash commands, rather than duplicating calling the low-level flash read/write/erase commands. This is a precursor to refactoring the low-level commands to support SPI/STM32L in a follow-up CL. BUG=chrome-os-partner:20571 BRANCH=none TEST=in a root shell, burn_my_ec flashes both RO and RW EC code Change-Id: I4c72690100d86dbff03b7dacc2fb248b571d3820 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/60266
This commit is contained in:
committed by
ChromeBot
parent
23dd3f5f9b
commit
267dbb74d2
@@ -7,7 +7,7 @@
|
||||
#
|
||||
|
||||
host-util-bin=ectool lbplay burn_my_ec
|
||||
host-util-common=ectool_keyscan comm-host comm-dev misc_util
|
||||
host-util-common=ectool_keyscan comm-host comm-dev misc_util ec_flash
|
||||
ifeq ($(CONFIG_LPC),y)
|
||||
host-util-common+=comm-lpc
|
||||
else
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "comm-host.h"
|
||||
#include "ec_flash.h"
|
||||
|
||||
#define STR0(name) #name
|
||||
#define STR(name) STR0(name)
|
||||
@@ -54,12 +55,7 @@ int flash_partition(enum ec_current_image part, const uint8_t *payload,
|
||||
uint32_t offset, uint32_t size)
|
||||
{
|
||||
struct ec_params_reboot_ec rst_req;
|
||||
struct ec_params_flash_erase er_req;
|
||||
struct ec_params_flash_write wr_req;
|
||||
struct ec_params_flash_read rd_req;
|
||||
uint8_t rd_resp[EC_HOST_PARAM_SIZE];
|
||||
int res;
|
||||
uint32_t i;
|
||||
enum ec_current_image current = EC_IMAGE_UNKNOWN;
|
||||
|
||||
res = get_version(¤t);
|
||||
@@ -74,15 +70,12 @@ int flash_partition(enum ec_current_image part, const uint8_t *payload,
|
||||
ec_command(EC_CMD_REBOOT_EC, 0, &rst_req, sizeof(rst_req),
|
||||
NULL, 0);
|
||||
/* wait EC reboot */
|
||||
usleep(500000);
|
||||
usleep(1000000);
|
||||
}
|
||||
|
||||
printf("Erasing partition %s : 0x%x bytes at 0x%08x\n",
|
||||
part_name[part], size, offset);
|
||||
er_req.size = size;
|
||||
er_req.offset = offset;
|
||||
res = ec_command(EC_CMD_FLASH_ERASE, 0,
|
||||
&er_req, sizeof(er_req), NULL, 0);
|
||||
res = ec_flash_erase(offset, size);
|
||||
if (res < 0) {
|
||||
fprintf(stderr, "Erase failed : %d\n", res);
|
||||
return -1;
|
||||
@@ -90,35 +83,20 @@ int flash_partition(enum ec_current_image part, const uint8_t *payload,
|
||||
|
||||
printf("Writing partition %s : 0x%x bytes at 0x%08x\n",
|
||||
part_name[part], size, offset);
|
||||
/* Write data in chunks */
|
||||
for (i = 0; i < size; i += sizeof(wr_req.data)) {
|
||||
wr_req.offset = offset + i;
|
||||
wr_req.size = MIN(size - i, sizeof(wr_req.data));
|
||||
memcpy(wr_req.data, payload + i, wr_req.size);
|
||||
res = ec_command(EC_CMD_FLASH_WRITE, 0,
|
||||
&wr_req, sizeof(wr_req), NULL, 0);
|
||||
if (res < 0) {
|
||||
fprintf(stderr, "Write error at 0x%08x : %d\n", i, res);
|
||||
return -1;
|
||||
}
|
||||
res = ec_flash_write(payload, offset, size);
|
||||
if (res < 0) {
|
||||
fprintf(stderr, "Write failed : %d\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Verifying partition %s : 0x%x bytes at 0x%08x\n",
|
||||
part_name[part], size, offset);
|
||||
/* Read data in chunks */
|
||||
for (i = 0; i < size; i += sizeof(rd_resp)) {
|
||||
rd_req.offset = offset + i;
|
||||
rd_req.size = MIN(size - i, sizeof(rd_resp));
|
||||
res = ec_command(EC_CMD_FLASH_READ, 0, &rd_req, sizeof(rd_req),
|
||||
&rd_resp, sizeof(rd_resp));
|
||||
if (res < 0) {
|
||||
fprintf(stderr, "Read error at 0x%08x : %d\n", i, res);
|
||||
return -1;
|
||||
}
|
||||
if (memcmp(payload + i, rd_resp, rd_req.size))
|
||||
fprintf(stderr, "ERR: @%08x->%08x\n",
|
||||
offset + i, offset + i + size);
|
||||
res = ec_flash_verify(payload, offset, size);
|
||||
if (res < 0) {
|
||||
fprintf(stderr, "Verify failed : %d\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Done.\n");
|
||||
|
||||
return get_version(NULL);
|
||||
|
||||
99
util/ec_flash.c
Normal file
99
util/ec_flash.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "comm-host.h"
|
||||
#include "misc_util.h"
|
||||
|
||||
int ec_flash_read(uint8_t *buf, int offset, int size)
|
||||
{
|
||||
struct ec_params_flash_read p;
|
||||
/* TODO(rspangler): need better way to determine max read size */
|
||||
uint8_t rdata[EC_HOST_PARAM_SIZE - sizeof(struct ec_host_response)];
|
||||
int rv;
|
||||
int i;
|
||||
|
||||
/* Read data in chunks */
|
||||
for (i = 0; i < size; i += sizeof(rdata)) {
|
||||
p.offset = offset + i;
|
||||
p.size = MIN(size - i, sizeof(rdata));
|
||||
rv = ec_command(EC_CMD_FLASH_READ, 0,
|
||||
&p, sizeof(p), rdata, sizeof(rdata));
|
||||
if (rv < 0) {
|
||||
fprintf(stderr, "Read error at offset %d\n", i);
|
||||
return rv;
|
||||
}
|
||||
memcpy(buf + i, rdata, p.size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ec_flash_verify(const uint8_t *buf, int offset, int size)
|
||||
{
|
||||
uint8_t *rbuf = malloc(size);
|
||||
int rv;
|
||||
int i;
|
||||
|
||||
if (!rbuf) {
|
||||
fprintf(stderr, "Unable to allocate buffer.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = ec_flash_read(rbuf, offset, size);
|
||||
if (rv < 0) {
|
||||
free(rbuf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (buf[i] != rbuf[i]) {
|
||||
fprintf(stderr, "Mismatch at offset 0x%x: "
|
||||
"want 0x%02x, got 0x%02x\n",
|
||||
i, buf[i], rbuf[i]);
|
||||
free(rbuf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
free(rbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ec_flash_write(const uint8_t *buf, int offset, int size)
|
||||
{
|
||||
struct ec_params_flash_write p;
|
||||
int rv;
|
||||
int i;
|
||||
|
||||
/* Write data in chunks */
|
||||
for (i = 0; i < size; i += sizeof(p.data)) {
|
||||
p.offset = offset + i;
|
||||
p.size = MIN(size - i, sizeof(p.data));
|
||||
memcpy(p.data, buf + i, p.size);
|
||||
rv = ec_command(EC_CMD_FLASH_WRITE, 0, &p, sizeof(p), NULL, 0);
|
||||
if (rv < 0) {
|
||||
fprintf(stderr, "Write error at offset %d\n", i);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
52
util/ec_flash.h
Normal file
52
util/ec_flash.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef __CROS_EC_EC_FLASH_H
|
||||
#define __CROS_EC_EC_FLASH_H
|
||||
|
||||
/**
|
||||
* Read EC flash memory
|
||||
*
|
||||
* @param buf Destination buffer
|
||||
* @param offset Offset in EC flash to read
|
||||
* @param size Number of bytes to read
|
||||
*
|
||||
* @return 0 if success, negative if error.
|
||||
*/
|
||||
int ec_flash_read(uint8_t *buf, int offset, int size);
|
||||
|
||||
/**
|
||||
* Verify EC flash memory
|
||||
*
|
||||
* @param buf Source buffer to verify against EC flash
|
||||
* @param offset Offset in EC flash to check
|
||||
* @param size Number of bytes to check
|
||||
*
|
||||
* @return 0 if success, negative if error.
|
||||
*/
|
||||
int ec_flash_verify(const uint8_t *buf, int offset, int size);
|
||||
|
||||
/**
|
||||
* Write EC flash memory
|
||||
*
|
||||
* @param buf Source buffer
|
||||
* @param offset Offset in EC flash to write
|
||||
* @param size Number of bytes to write
|
||||
*
|
||||
* @return 0 if success, negative if error.
|
||||
*/
|
||||
int ec_flash_write(const uint8_t *buf, int offset, int size);
|
||||
|
||||
/**
|
||||
* Erase EC flash memory
|
||||
*
|
||||
* @param offset Offset in EC flash to erase
|
||||
* @param size Number of bytes to erase
|
||||
*
|
||||
* @return 0 if success, negative if error.
|
||||
*/
|
||||
int ec_flash_erase(int offset, int size);
|
||||
|
||||
#endif
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "battery.h"
|
||||
#include "comm-host.h"
|
||||
#include "compile_time_macros.h"
|
||||
#include "ec_flash.h"
|
||||
#include "ectool.h"
|
||||
#include "lightbar.h"
|
||||
#include "lock/gec_lock.h"
|
||||
@@ -487,14 +488,10 @@ int cmd_flash_info(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int cmd_flash_read(int argc, char *argv[])
|
||||
{
|
||||
struct ec_params_flash_read p;
|
||||
uint8_t rdata[EC_HOST_PARAM_SIZE];
|
||||
int offset, size;
|
||||
int rv;
|
||||
int i;
|
||||
char *e;
|
||||
char *buf;
|
||||
|
||||
@@ -522,17 +519,10 @@ int cmd_flash_read(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* Read data in chunks */
|
||||
for (i = 0; i < size; i += sizeof(rdata)) {
|
||||
p.offset = offset + i;
|
||||
p.size = MIN(size - i, sizeof(rdata));
|
||||
rv = ec_command(EC_CMD_FLASH_READ, 0,
|
||||
&p, sizeof(p), rdata, sizeof(rdata));
|
||||
if (rv < 0) {
|
||||
fprintf(stderr, "Read error at offset %d\n", i);
|
||||
free(buf);
|
||||
return rv;
|
||||
}
|
||||
memcpy(buf + i, rdata, p.size);
|
||||
rv = ec_flash_read(buf, offset, size);
|
||||
if (rv < 0) {
|
||||
free(buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = write_file(argv[3], buf, size);
|
||||
@@ -544,13 +534,10 @@ int cmd_flash_read(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int cmd_flash_write(int argc, char *argv[])
|
||||
{
|
||||
struct ec_params_flash_write p;
|
||||
int offset, size;
|
||||
int rv;
|
||||
int i;
|
||||
char *e;
|
||||
char *buf;
|
||||
|
||||
@@ -558,6 +545,7 @@ int cmd_flash_write(int argc, char *argv[])
|
||||
fprintf(stderr, "Usage: %s <offset> <filename>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
offset = strtol(argv[1], &e, 0);
|
||||
if ((e && *e) || offset < 0 || offset > 0x100000) {
|
||||
fprintf(stderr, "Bad offset.\n");
|
||||
@@ -572,27 +560,20 @@ int cmd_flash_write(int argc, char *argv[])
|
||||
printf("Writing to offset %d...\n", offset);
|
||||
|
||||
/* Write data in chunks */
|
||||
for (i = 0; i < size; i += sizeof(p.data)) {
|
||||
p.offset = offset + i;
|
||||
p.size = MIN(size - i, sizeof(p.data));
|
||||
memcpy(p.data, buf + i, p.size);
|
||||
rv = ec_command(EC_CMD_FLASH_WRITE, 0, &p, sizeof(p), NULL, 0);
|
||||
if (rv < 0) {
|
||||
fprintf(stderr, "Write error at offset %d\n", i);
|
||||
free(buf);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
rv = ec_flash_write(buf, offset, size);
|
||||
|
||||
free(buf);
|
||||
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
printf("done.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int cmd_flash_erase(int argc, char *argv[])
|
||||
{
|
||||
struct ec_params_flash_erase p;
|
||||
int offset, size;
|
||||
char *e;
|
||||
int rv;
|
||||
|
||||
@@ -600,19 +581,21 @@ int cmd_flash_erase(int argc, char *argv[])
|
||||
fprintf(stderr, "Usage: %s <offset> <size>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
p.offset = strtol(argv[1], &e, 0);
|
||||
if ((e && *e) || p.offset < 0 || p.offset > 0x100000) {
|
||||
|
||||
offset = strtol(argv[1], &e, 0);
|
||||
if ((e && *e) || offset < 0 || offset > 0x100000) {
|
||||
fprintf(stderr, "Bad offset.\n");
|
||||
return -1;
|
||||
}
|
||||
p.size = strtol(argv[2], &e, 0);
|
||||
if ((e && *e) || p.size <= 0 || p.size > 0x100000) {
|
||||
|
||||
size = strtol(argv[2], &e, 0);
|
||||
if ((e && *e) || size <= 0 || size > 0x100000) {
|
||||
fprintf(stderr, "Bad size.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Erasing %d bytes at offset %d...\n", p.size, p.offset);
|
||||
rv = ec_command(EC_CMD_FLASH_ERASE, 0, &p, sizeof(p), NULL, 0);
|
||||
printf("Erasing %d bytes at offset %d...\n", size, offset);
|
||||
rv = ec_flash_erase(offset, size);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user