[Intel-gfx] [i-g-t PATCH 3/5] intel_bios_reader: rewrite the mipi sequence block dumping
Jani Nikula
jani.nikula at intel.com
Mon Dec 21 07:05:54 PST 2015
Simplify things a lot, make it correct, don't pass random pointers to
free() on errors, etc.
Signed-off-by: Jani Nikula <jani.nikula at intel.com>
---
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
More information about the Intel-gfx
mailing list