summaryrefslogtreecommitdiffstats
path: root/scripts/imx
diff options
context:
space:
mode:
authorAlexander Kurz <akurz@blala.de>2017-02-19 19:57:58 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2017-02-22 09:18:30 +0100
commitf0a2d7f036a7a7e9603814504e483f91393fdeed (patch)
tree19a974f8ccdf42f27eea93329b874ec9c32bc5b9 /scripts/imx
parent8175ff1df44b7041cb0fb0e747d9c57c92d5176c (diff)
downloadbarebox-f0a2d7f036a7a7e9603814504e483f91393fdeed.tar.gz
barebox-f0a2d7f036a7a7e9603814504e483f91393fdeed.tar.xz
scripts: imx-usb-loader: implement DCD v2 check command
The DCD v2 check command supported by i.MX53 and later SoC polls a given memory location as long as a given condition is true. Enable imx-usb-loader to perform this check. When the timeout is hit, imx-usb-loader returns an error. For practical reasons the timeout computation will differ from the native implementation, since performing check commands via USB will be much slower compared to native processing. Signed-off-by: Alexander Kurz <akurz@blala.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'scripts/imx')
-rw-r--r--scripts/imx/imx-usb-loader.c95
-rw-r--r--scripts/imx/imx.h16
2 files changed, 109 insertions, 2 deletions
diff --git a/scripts/imx/imx-usb-loader.c b/scripts/imx/imx-usb-loader.c
index 9de7bb3a8a..4105adeda9 100644
--- a/scripts/imx/imx-usb-loader.c
+++ b/scripts/imx/imx-usb-loader.c
@@ -798,6 +798,98 @@ static int do_dcd_v2_cmd_write(const unsigned char *dcd)
return 0;
}
+static int do_dcd_v2_cmd_check(const unsigned char *dcd)
+{
+ uint32_t mask;
+ uint32_t poll_count = 0;
+ int bytes;
+ enum imx_dcd_v2_check_cond cond;
+ struct imx_dcd_v2_check *check = (struct imx_dcd_v2_check *) dcd;
+ switch (ntohs(check->length)) {
+ case 12:
+ /* poll indefinitely */
+ poll_count = 0xffffffff;
+ break;
+ case 16:
+ poll_count = ntohl(check->count);
+ if (poll_count == 0)
+ /* this command behaves as for NOP */
+ return 0;
+ break;
+ default:
+ fprintf(stderr, "Error: invalid DCD check length\n");
+ return -1;
+ }
+
+ switch (check->param & 7) {
+ case 1:
+ case 2:
+ case 4:
+ bytes = check->param & 7;
+ break;
+ default:
+ fprintf(stderr, "Error: invalid DCD check size\n");
+ return -1;
+ }
+
+ switch ((check->param & 0xf8) >> 3) {
+ case check_all_bits_clear:
+ case check_all_bits_set:
+ case check_any_bit_clear:
+ case check_any_bit_set:
+ cond = (check->param & 0xf8) >> 3;
+ break;
+ default:
+ fprintf(stderr, "Error: invalid DCD check condition\n");
+ return -1;
+ }
+
+ mask = ntohl(check->mask);
+
+ fprintf(stderr, "DCD check condition %i on address 0x%x\n",
+ cond, ntohl(check->addr));
+ /* Reduce the poll count to some arbitrary practical limit.
+ Polling via SRP commands will be much slower compared to
+ polling when DCD is interpreted by the SOC microcode.
+ */
+ if (poll_count > 1000)
+ poll_count = 1000;
+
+ while (poll_count > 0) {
+ uint32_t data = 0;
+ int ret = read_memory(ntohl(check->addr), &data, bytes);
+ if (ret < 0)
+ return ret;
+
+ data &= mask;
+
+ switch (cond) {
+ case check_all_bits_clear:
+ if (data != 0)
+ return 0;
+ break;
+ case check_all_bits_set:
+ if (data != mask)
+ return 0;
+ break;
+ case check_any_bit_clear:
+ if (data == mask)
+ return 0;
+ break;
+ case check_any_bit_set:
+ if (data == 0)
+ return 0;
+ break;
+ }
+ poll_count--;
+ }
+
+ fprintf(stderr, "Error: timeout waiting for DCD check condition %i "
+ "on address 0x%08x to match 0x%08x\n", cond,
+ ntohl(check->addr), ntohl(check->mask));
+ return -1;
+}
+
static int process_dcd_table_ivt(const struct imx_flash_header_v2 *hdr,
const unsigned char *file_start, unsigned cnt)
{
@@ -850,8 +942,7 @@ static int process_dcd_table_ivt(const struct imx_flash_header_v2 *hdr,
ret = do_dcd_v2_cmd_write(dcd);
break;
case TAG_CHECK:
- fprintf(stderr, "DCD check not implemented yet\n");
- usleep(50000);
+ ret = do_dcd_v2_cmd_check(dcd);
break;
case TAG_UNLOCK:
fprintf(stderr, "DCD unlock not implemented yet\n");
diff --git a/scripts/imx/imx.h b/scripts/imx/imx.h
index 57c7525369..f32ae52abf 100644
--- a/scripts/imx/imx.h
+++ b/scripts/imx/imx.h
@@ -95,4 +95,20 @@ struct imx_dcd_v2_write {
struct imx_dcd_v2_write_rec data[MAX_RECORDS_DCD_V2];
} __attribute__((packed));
+struct imx_dcd_v2_check {
+ uint8_t tag;
+ uint16_t length;
+ uint8_t param;
+ uint32_t addr;
+ uint32_t mask;
+ uint32_t count;
+} __attribute__((packed));
+
+enum imx_dcd_v2_check_cond {
+ check_all_bits_clear = 0,
+ check_all_bits_set = 1,
+ check_any_bit_clear = 2,
+ check_any_bit_set = 3,
+} __attribute__((packed));
+
int parse_config(struct config_data *data, const char *filename);