On Sun, Feb 19, 2017 at 07:57:58PM +0100, Alexander Kurz wrote: > 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@xxxxxxxx> Nice work. Applied, thanks Sascha > --- > scripts/imx/imx-usb-loader.c | 95 +++++++++++++++++++++++++++++++++++++++++++- > scripts/imx/imx.h | 16 ++++++++ > 2 files changed, 109 insertions(+), 2 deletions(-) > > diff --git a/scripts/imx/imx-usb-loader.c b/scripts/imx/imx-usb-loader.c > index 9de7bb3..4105ade 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 57c7525..f32ae52 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); > -- > 2.1.4 > > > _______________________________________________ > barebox mailing list > barebox@xxxxxxxxxxxxxxxxxxx > http://lists.infradead.org/mailman/listinfo/barebox > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox