Simplify things a lot, make it correct, don't pass random pointers to
free() on errors, etc.

Signed-off-by: Jani Nikula <[email protected]>
---
 tools/intel_bios.h        |  19 ++--
 tools/intel_bios_reader.c | 224 +++++++++++++---------------------------------
 2 files changed, 78 insertions(+), 165 deletions(-)

diff --git a/tools/intel_bios.h b/tools/intel_bios.h
index 6135a2b47055..b7ebd48ef7e7 100644
--- a/tools/intel_bios.h
+++ b/tools/intel_bios.h
@@ -763,22 +763,31 @@ struct bdb_mipi_sequence {
        uint8_t data[0];
 } __attribute__ ((packed));
 
-/* MIPI Sequnece Block definitions */
-enum MIPI_SEQ {
-       MIPI_SEQ_UNDEFINED = 0,
+/* MIPI Sequence Block definitions */
+enum mipi_seq {
+       MIPI_SEQ_END = 0,
        MIPI_SEQ_ASSERT_RESET,
        MIPI_SEQ_INIT_OTP,
        MIPI_SEQ_DISPLAY_ON,
        MIPI_SEQ_DISPLAY_OFF,
        MIPI_SEQ_DEASSERT_RESET,
+       MIPI_SEQ_BACKLIGHT_ON,          /* sequence block v2+ */
+       MIPI_SEQ_BACKLIGHT_OFF,         /* sequence block v2+ */
+       MIPI_SEQ_TEAR_ON,               /* sequence block v2+ */
+       MIPI_SEQ_TEAR_OFF,              /* sequence block v3+ */
+       MIPI_SEQ_POWER_ON,              /* sequence block v3+ */
+       MIPI_SEQ_POWER_OFF,             /* sequence block v3+ */
        MIPI_SEQ_MAX
 };
 
-enum MIPI_SEQ_ELEMENT {
-       MIPI_SEQ_ELEM_UNDEFINED = 0,
+enum mipi_seq_element {
+       MIPI_SEQ_ELEM_END = 0,
        MIPI_SEQ_ELEM_SEND_PKT,
        MIPI_SEQ_ELEM_DELAY,
        MIPI_SEQ_ELEM_GPIO,
+       MIPI_SEQ_ELEM_I2C,              /* sequence block v2+ */
+       MIPI_SEQ_ELEM_SPI,              /* sequence block v3+ */
+       MIPI_SEQ_ELEM_PMIC,             /* sequence block v3+ */
        MIPI_SEQ_ELEM_MAX
 };
 
diff --git a/tools/intel_bios_reader.c b/tools/intel_bios_reader.c
index 09ca50d44a77..1b1cb6bc8ebf 100644
--- a/tools/intel_bios_reader.c
+++ b/tools/intel_bios_reader.c
@@ -71,15 +71,6 @@ struct bdb_block {
        void *data;
 };
 
-static const char * const seq_name[] = {
-       "UNDEFINED",
-       "MIPI_SEQ_ASSERT_RESET",
-       "MIPI_SEQ_INIT_OTP",
-       "MIPI_SEQ_DISPLAY_ON",
-       "MIPI_SEQ_DISPLAY_OFF",
-       "MIPI_SEQ_DEASSERT_RESET",
-};
-
 struct bdb_header *bdb;
 struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs;
 static int tv_present;
@@ -858,7 +849,7 @@ static void dump_mipi_config(const struct bdb_block *block)
        printf("\t\tPanel power cycle delay: %d\n", 
pps->panel_power_cycle_delay);
 }
 
-static uint8_t *mipi_dump_send_packet(uint8_t *data)
+static const uint8_t *mipi_dump_send_packet(const uint8_t *data)
 {
        uint8_t type, byte, count;
        uint16_t len;
@@ -878,14 +869,14 @@ static uint8_t *mipi_dump_send_packet(uint8_t *data)
        return data;
 }
 
-static uint8_t *mipi_dump_delay(uint8_t *data)
+static const uint8_t *mipi_dump_delay(const uint8_t *data)
 {
        printf("\t\t Delay : 0x%x 0x%x 0x%x 0x%x\n", data[0], data[1], data[2], 
data[3]);
        data += 4;
        return data;
 }
 
-static uint8_t *mipi_dump_gpio(uint8_t *data)
+static const uint8_t *mipi_dump_gpio(const uint8_t *data)
 {
        uint8_t gpio, action;
 
@@ -898,119 +889,66 @@ static uint8_t *mipi_dump_gpio(uint8_t *data)
        return data;
 }
 
-typedef uint8_t * (*fn_mipi_elem_dump)(uint8_t *data);
+typedef const uint8_t * (*fn_mipi_elem_dump)(const uint8_t *data);
 
 static const fn_mipi_elem_dump dump_elem[] = {
-       NULL, /* reserved */
-       mipi_dump_send_packet,
-       mipi_dump_delay,
-       mipi_dump_gpio,
-       NULL, /* status read; later */
+       [MIPI_SEQ_ELEM_SEND_PKT] = mipi_dump_send_packet,
+       [MIPI_SEQ_ELEM_DELAY] = mipi_dump_delay,
+       [MIPI_SEQ_ELEM_GPIO] = mipi_dump_gpio,
 };
 
-static void dump_sequence(uint8_t *sequence)
-{
-       uint8_t *data = sequence;
-       fn_mipi_elem_dump mipi_elem_dump;
-       int index_no;
-
-       if (!sequence)
-               return;
-
-       printf("\tSequence Name: %s\n", seq_name[*data]);
-
-       /* go to the first element of the sequence */
-       data++;
-
-       /* parse each byte till we reach end of sequence byte - 0x00 */
-       while (1) {
-               index_no = *data;
-               mipi_elem_dump = dump_elem[index_no];
-               if (!mipi_elem_dump) {
-                       printf("Error: Unsupported MIPI element, skipping 
sequence execution\n");
-                       return;
-               }
-               /* goto element payload */
-               data++;
-
-               /* execute the element specifc rotines */
-               data = mipi_elem_dump(data);
-
-               /*
-                * After processing the element, data should point to
-                * next element or end of sequence
-                * check if have we reached end of sequence
-                */
+static const char * const seq_name[] = {
+       [MIPI_SEQ_ASSERT_RESET] = "MIPI_SEQ_ASSERT_RESET",
+       [MIPI_SEQ_INIT_OTP] = "MIPI_SEQ_INIT_OTP",
+       [MIPI_SEQ_DISPLAY_ON] = "MIPI_SEQ_DISPLAY_ON",
+       [MIPI_SEQ_DISPLAY_OFF]  = "MIPI_SEQ_DISPLAY_OFF",
+       [MIPI_SEQ_DEASSERT_RESET] = "MIPI_SEQ_DEASSERT_RESET",
+       [MIPI_SEQ_BACKLIGHT_ON] = "MIPI_SEQ_BACKLIGHT_ON",
+       [MIPI_SEQ_BACKLIGHT_OFF] = "MIPI_SEQ_BACKLIGHT_OFF",
+       [MIPI_SEQ_TEAR_ON] = "MIPI_SEQ_TEAR_ON",
+       [MIPI_SEQ_TEAR_OFF] = "MIPI_SEQ_TEAR_OFF",
+       [MIPI_SEQ_POWER_ON] = "MIPI_SEQ_POWER_ON",
+       [MIPI_SEQ_POWER_OFF] = "MIPI_SEQ_POWER_OFF",
+};
 
-               if (*data == 0x00)
-                       break;
-       }
+static const char *sequence_name(enum mipi_seq seq_id)
+{
+       if (seq_id < ARRAY_SIZE(seq_name) && seq_name[seq_id])
+               return seq_name[seq_id];
+       else
+               return "(unknown)";
 }
 
-static uint8_t *goto_next_sequence(uint8_t *data, int *size)
+static const uint8_t *dump_sequence(const uint8_t *data)
 {
-       uint16_t len;
-       int tmp = *size;
+       fn_mipi_elem_dump mipi_elem_dump;
 
-       if (--tmp < 0)
-               return NULL;
+       printf("\tSequence %u - %s\n", *data, sequence_name(*data));
 
-       /* goto first element */
+       /* Skip Sequence Byte. */
        data++;
-       while (1) {
-               switch (*data) {
-               case MIPI_SEQ_ELEM_SEND_PKT:
-                       /*
-                        * skip by this element payload size
-                        * skip elem id, command flag and data type
-                        */
-                       tmp -= 5;
-                       if (tmp < 0)
-                               return NULL;
-
-                       data += 3;
-                       len = *((uint16_t *)data);
-
-                       tmp -= len;
-                       if (tmp < 0)
-                               return NULL;
-
-                       /* skip by len */
-                       data = data + 2 + len;
-                       break;
-               case MIPI_SEQ_ELEM_DELAY:
-                       /* skip by elem id, and delay is 4 bytes */
-                       tmp -= 5;
-                       if (tmp < 0)
-                               return NULL;
 
-                       data += 5;
-                       break;
-               case MIPI_SEQ_ELEM_GPIO:
-                       tmp -= 3;
-                       if (tmp < 0)
-                               return NULL;
-
-                       data += 3;
-                       break;
-               default:
-                       printf("Unknown element\n");
-                       return NULL;
-                }
+       while (1) {
+               uint8_t operation_byte = *data++;
 
-               /* end of sequence ? */
-               if (*data == 0)
+               if (operation_byte == MIPI_SEQ_ELEM_END)
                        break;
-        }
 
-       /* goto next sequence or end of block byte */
-       if (--tmp < 0)
-               return NULL;
+               if (operation_byte < ARRAY_SIZE(dump_elem) &&
+                   dump_elem[operation_byte])
+                       mipi_elem_dump = dump_elem[operation_byte];
+               else
+                       mipi_elem_dump = NULL;
 
-        data++;
+               if (mipi_elem_dump) {
+                       data = mipi_elem_dump(data);
+               } else {
+                       printf("Error: Unsupported MIPI element %u\n",
+                              operation_byte);
+                       return NULL;
+               }
+       }
 
-       /* update amount of data left for the sequence block to be parsed */
-       *size = tmp;
        return data;
 }
 
@@ -1026,7 +964,7 @@ static uint16_t get_blocksize(void *p)
 static void dump_mipi_sequence(const struct bdb_block *block)
 {
        struct bdb_mipi_sequence *sequence = block->data;
-       uint8_t *data, *seq_data;
+       const uint8_t *data;
        int i, panel_id, seq_size;
        uint16_t block_size;
 
@@ -1043,27 +981,26 @@ static void dump_mipi_sequence(const struct bdb_block 
*block)
 
        block_size = get_blocksize(sequence);
 
-       /*
-        * parse the sequence block for individual sequences
-        */
-       seq_data = &sequence->data[0];
+       data = &sequence->data[0];
 
        /*
         * sequence block is variable length and hence we need to parse and
         * get the sequence data for specific panel id
         */
        for (i = 0; i < MAX_MIPI_CONFIGURATIONS; i++) {
-               panel_id = *seq_data;
-               seq_size = *((uint16_t *) (seq_data + 1));
-               if (panel_id == panel_type)
-                       break;
+               panel_id = *data;
+               seq_size = *((uint16_t *) (data + 1));
+               data += 3;
 
-               /* skip the sequence including seq header of 3 bytes */
-               seq_data = seq_data + 3 + seq_size;
-               if ((seq_data - &sequence->data[0]) > block_size) {
-                       printf("Sequence start is beyond sequence block size, 
corrupted sequence block\n");
+               if (data + seq_size > (const uint8_t *)sequence + block_size) {
+                       printf("Invalid sequence block\n");
                        return;
                }
+
+               if (panel_id == panel_type)
+                       break;
+
+               data += seq_size;
        }
 
        if (i == MAX_MIPI_CONFIGURATIONS) {
@@ -1071,55 +1008,22 @@ static void dump_mipi_sequence(const struct bdb_block 
*block)
                return;
        }
 
-       /* check if found sequence is completely within the sequence block
-        * just being paranoid */
-       if (seq_size > block_size) {
-               printf("Corrupted sequence/size, bailing out\n");
-               return;
-        }
-
-       /* skip the panel id(1 byte) and seq size(2 bytes) */
-       data = (uint8_t *) calloc(1, seq_size);
-       if (data)
-               memmove(data, seq_data + 3, seq_size);
-       else {
-               printf("Memory not allocated for sequence data\n");
-               return;
-       }
        /*
         * loop into the sequence data and split into multiple sequneces
         * There are only 5 types of sequences as of now
         */
 
-       /* two consecutive 0x00 indicate end of all sequences */
         while (1) {
                int seq_id = *data;
-               if (MIPI_SEQ_MAX > seq_id && seq_id > MIPI_SEQ_UNDEFINED)
-                       dump_sequence(data);
-                else {
-                       printf("Error:undefined sequence\n");
-                       goto err;
-                }
-
-               /* partial parsing to skip elements */
-               data = goto_next_sequence(data, &seq_size);
-
-               if (data == NULL) {
-                       printf("Sequence elements going beyond block itself. 
Sequence block parsing failed\n");
-                       goto err;
-                }
-
-               if (*data == 0)
-                       break; /* end of sequence reached */
-       }
-        return;
+               if (seq_id == MIPI_SEQ_END)
+                       break;
 
-err:
-       free(data);
-       data = NULL;
+               data = dump_sequence(data);
+               if (!data)
+                       break;
+       }
 }
 
-
 static int
 get_device_id(unsigned char *bios, int size)
 {
-- 
2.1.4

_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to