]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
imximage: fix commands other than write_data
authorTroy Kisky <troy.kisky@boundarydevices.com>
Tue, 15 Sep 2015 01:06:31 +0000 (18:06 -0700)
committerStefano Babic <sbabic@denx.de>
Wed, 7 Oct 2015 11:43:15 +0000 (13:43 +0200)
When CHECK_BITS_SET was added, they forgot to add
a new command table, and instead overwrote the
previous table.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Tested-by: Fabio Estevam <fabio.estevam@freescale.com>
tools/imximage.c
tools/imximage.h

index 7e60bf5d3964f4f0213ee5d21e78ec6c232b76ec..7c219222e9f4cd73e06d57cb69c66bfebeba0f88 100644 (file)
@@ -160,54 +160,80 @@ static void set_dcd_val_v1(struct imx_header *imxhdr, char *name, int lineno,
        }
 }
 
+static struct dcd_v2_cmd *gd_last_cmd;
+
 static void set_dcd_param_v2(struct imx_header *imxhdr, uint32_t dcd_len,
                int32_t cmd)
 {
        dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
+       struct dcd_v2_cmd *d = gd_last_cmd;
+       struct dcd_v2_cmd *d2;
+       int len;
+
+       if (!d)
+               d = &dcd_v2->dcd_cmd;
+       d2 = d;
+       len = be16_to_cpu(d->write_dcd_command.length);
+       if (len > 4)
+               d2 = (struct dcd_v2_cmd *)(((char *)d) + len);
 
        switch (cmd) {
        case CMD_WRITE_DATA:
-               dcd_v2->write_dcd_command.tag = DCD_WRITE_DATA_COMMAND_TAG;
-               dcd_v2->write_dcd_command.length = cpu_to_be16(
-                               dcd_len * sizeof(dcd_addr_data_t) + 4);
-               dcd_v2->write_dcd_command.param = DCD_WRITE_DATA_PARAM;
+               if ((d->write_dcd_command.tag == DCD_WRITE_DATA_COMMAND_TAG) &&
+                   (d->write_dcd_command.param == DCD_WRITE_DATA_PARAM))
+                       break;
+               d = d2;
+               d->write_dcd_command.tag = DCD_WRITE_DATA_COMMAND_TAG;
+               d->write_dcd_command.length = cpu_to_be16(4);
+               d->write_dcd_command.param = DCD_WRITE_DATA_PARAM;
                break;
        case CMD_WRITE_CLR_BIT:
-               dcd_v2->write_dcd_command.tag = DCD_WRITE_DATA_COMMAND_TAG;
-               dcd_v2->write_dcd_command.length = cpu_to_be16(
-                               dcd_len * sizeof(dcd_addr_data_t) + 4);
-               dcd_v2->write_dcd_command.param = DCD_WRITE_CLR_BIT_PARAM;
+               if ((d->write_dcd_command.tag == DCD_WRITE_DATA_COMMAND_TAG) &&
+                   (d->write_dcd_command.param == DCD_WRITE_CLR_BIT_PARAM))
+                       break;
+               d = d2;
+               d->write_dcd_command.tag = DCD_WRITE_DATA_COMMAND_TAG;
+               d->write_dcd_command.length = cpu_to_be16(4);
+               d->write_dcd_command.param = DCD_WRITE_CLR_BIT_PARAM;
                break;
        /*
         * Check data command only supports one entry,
-        * so use 0xC = size(address + value + command).
         */
        case CMD_CHECK_BITS_SET:
-               dcd_v2->write_dcd_command.tag = DCD_CHECK_DATA_COMMAND_TAG;
-               dcd_v2->write_dcd_command.length = cpu_to_be16(0xC);
-               dcd_v2->write_dcd_command.param = DCD_CHECK_BITS_SET_PARAM;
+               d = d2;
+               d->write_dcd_command.tag = DCD_CHECK_DATA_COMMAND_TAG;
+               d->write_dcd_command.length = cpu_to_be16(4);
+               d->write_dcd_command.param = DCD_CHECK_BITS_SET_PARAM;
                break;
        case CMD_CHECK_BITS_CLR:
-               dcd_v2->write_dcd_command.tag = DCD_CHECK_DATA_COMMAND_TAG;
-               dcd_v2->write_dcd_command.length = cpu_to_be16(0xC);
-               dcd_v2->write_dcd_command.param = DCD_CHECK_BITS_SET_PARAM;
+               d = d2;
+               d->write_dcd_command.tag = DCD_CHECK_DATA_COMMAND_TAG;
+               d->write_dcd_command.length = cpu_to_be16(4);
+               d->write_dcd_command.param = DCD_CHECK_BITS_SET_PARAM;
                break;
        default:
                break;
        }
+       gd_last_cmd = d;
 }
 
 static void set_dcd_val_v2(struct imx_header *imxhdr, char *name, int lineno,
                                        int fld, uint32_t value, uint32_t off)
 {
-       dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
+       struct dcd_v2_cmd *d = gd_last_cmd;
+       int len;
+
+       len = be16_to_cpu(d->write_dcd_command.length);
+       off = (len - 4) >> 3;
 
        switch (fld) {
        case CFG_REG_ADDRESS:
-               dcd_v2->addr_data[off].addr = cpu_to_be32(value);
+               d->addr_data[off].addr = cpu_to_be32(value);
                break;
        case CFG_REG_VALUE:
-               dcd_v2->addr_data[off].value = cpu_to_be32(value);
+               d->addr_data[off].value = cpu_to_be32(value);
+               off++;
+               d->write_dcd_command.length = cpu_to_be16((off << 3) + 4);
                break;
        default:
                break;
@@ -236,12 +262,20 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
                                                char *name, int lineno)
 {
        dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
+       struct dcd_v2_cmd *d = gd_last_cmd;
+       int len;
+
+       if (!d)
+               d = &dcd_v2->dcd_cmd;
+       len = be16_to_cpu(d->write_dcd_command.length);
+       if (len > 4)
+               d = (struct dcd_v2_cmd *)(((char *)d) + len);
+
+       len = (char *)d - (char *)&dcd_v2->header;
 
        dcd_v2->header.tag = DCD_HEADER_TAG;
-       dcd_v2->header.length = cpu_to_be16(
-                       dcd_len * sizeof(dcd_addr_data_t) + 8);
+       dcd_v2->header.length = cpu_to_be16(len);
        dcd_v2->header.version = DCD_VERSION;
-       set_dcd_param_v2(imxhdr, dcd_len, CMD_WRITE_DATA);
 }
 
 static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
@@ -314,6 +348,7 @@ static void set_hdr_func(void)
                max_dcd_entries = MAX_HW_CFG_SIZE_V1;
                break;
        case IMXIMAGE_V2:
+               gd_last_cmd = NULL;
                set_dcd_val = set_dcd_val_v2;
                set_dcd_param = set_dcd_param_v2;
                set_dcd_rst = set_dcd_rst_v2;
index d41c74f327e070f6503ee427cc4821f4289c5c4b..c7b9b5c8cc41fea8c409fd43175f8956e276985c 100644 (file)
@@ -133,10 +133,14 @@ typedef struct {
        uint8_t param;
 } __attribute__((packed)) write_dcd_command_t;
 
-typedef struct {
-       ivt_header_t header;
+struct dcd_v2_cmd {
        write_dcd_command_t write_dcd_command;
        dcd_addr_data_t addr_data[MAX_HW_CFG_SIZE_V2];
+};
+
+typedef struct {
+       ivt_header_t header;
+       struct dcd_v2_cmd dcd_cmd;
        uint32_t padding[1]; /* end up on an 8-byte boundary */
 } dcd_v2_t;