Edward O'Callaghan has uploaded this change for review.

View Change

poc json chip entry parser

Change-Id: If3e591468a60cb8846860e8b4ac1978b33f11aec
Signed-off-by: Edward O'Callaghan <quasisec@google.com>
---
A subprojects/chip.txt
A subprojects/json_chip.c
2 files changed, 297 insertions(+), 0 deletions(-)

git pull ssh://review.coreboot.org:29418/flashrom refs/changes/10/69610/1
diff --git a/subprojects/chip.txt b/subprojects/chip.txt
new file mode 100644
index 0000000..7b06889
--- /dev/null
+++ b/subprojects/chip.txt
@@ -0,0 +1,45 @@
+ {
+ "vendor" : "Winbond",
+ "name" : "W25Q128.V",
+ "bustype" : BUS_SPI,
+ "manufacture_id": WINBOND_NEX_ID,
+ "model_id" : WINBOND_NEX_W25Q128_V,
+ "total_size" : 16384,
+ "page_size" : 256,
+ "feature_bits" : [FEATURE_WRSR_WREN, FEATURE_OTP, FEATURE_WRSR_EXT2, FEATURE_WRSR2, FEATURE_WRSR3],
+ "tested" : TEST_OK_PREW,
+ "probe" : PROBE_SPI_RDID,
+ "probe_timing" : TIMING_ZERO,
+ "block_erasers" :
+ [
+ {
+ "eraseblocks" : [4 * 1024, 4096],
+ "block_erase" : SPI_BLOCK_ERASE_20,
+ }, {
+ "eraseblocks" : [32 * 1024, 512],
+ "block_erase" : SPI_BLOCK_ERASE_52,
+ }, {
+ "eraseblocks" : [64 * 1024, 256],
+ "block_erase" : SPI_BLOCK_ERASE_D8,
+ }, {
+ "eraseblocks" : [16 * 1024 * 1024, 1],
+ "block_erase" : SPI_BLOCK_ERASE_60,
+ }, {
+ "eraseblocks" : [16 * 1024 * 1024, 1],
+ "block_erase" : SPI_BLOCK_ERASE_C7,
+ }
+ ],
+ "write" : SPI_CHIP_WRITE256,
+ "read" : SPI_CHIP_READ,
+ "voltage" : [2700, 3600],
+ "reg_bits" :
+ {
+ "srp" : [STATUS1, 7, RW],
+ "srl" : [STATUS2, 0, RW],
+ "tb" : [STATUS1, 5, RW],
+ "sec" : [STATUS1, 6, RW],
+ "cmp" : [STATUS2, 6, RW],
+ "wps" : [STATUS3, 2, RW],
+ },
+ "decode_range" : DECODE_RANGE_SPI25,
+ },
diff --git a/subprojects/json_chip.c b/subprojects/json_chip.c
new file mode 100644
index 0000000..ad16fc1
--- /dev/null
+++ b/subprojects/json_chip.c
@@ -0,0 +1,242 @@
+#include "jsmn/jsmn.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* JSONify flashchips db worked example. */
+
+static int jsoneq (const char *json, jsmntok_t *tok, const char *s) {
+ if (tok->type == JSMN_STRING && (int)strlen (s) == tok->end - tok->start &&
+ strncmp (json + tok->start, s, tok->end - tok->start) == 0) {
+ return 0;
+ }
+ return -1;
+}
+
+int main () {
+ int i;
+ int r;
+ jsmn_parser p;
+ jsmntok_t t[128] = {0}; /* no. of expected tokens */
+ char *data = NULL;
+
+ FILE *fp = fopen ("chip.txt", "r");
+ if (fp) {
+ if (fseek (fp, 0L, SEEK_END) == 0) {
+ long bufsize = ftell (fp);
+ if (bufsize == -1) {
+ exit (1);
+ }
+
+ data = malloc (sizeof (char) * (bufsize + 1));
+
+ if (fseek (fp, 0L, SEEK_SET) != 0) {
+ free (data);
+ exit (1);
+ }
+
+ size_t newLen = fread (data, sizeof (char), bufsize, fp);
+ if (ferror (fp) != 0) {
+ fputs ("Error reading file", stderr);
+ } else {
+ data[newLen++] = '\0';
+ }
+ }
+ fclose (fp);
+ }
+
+ jsmn_init (&p);
+ r = jsmn_parse (&p, data, strlen (data), t, sizeof (t) / sizeof (t[0]));
+ if (r < 0) {
+ printf ("Failed to parse JSON: %d\n", r);
+ return 1;
+ }
+
+ /* Assume the top-level element is an object */
+ if (r < 1 || t[0].type != JSMN_OBJECT) {
+ printf ("Object expected\n");
+ return 1;
+ }
+
+ /* Loop over all keys of the root object */
+ for (i = 1; i < r; i++) {
+ if (jsoneq (data, &t[i], "vendor") == 0) {
+ /* We may use strndup() to fetch string value */
+ printf ("- vendor: %.*s\n", t[i + 1].end - t[i + 1].start,
+ data + t[i + 1].start);
+ i++;
+ } else if (jsoneq (data, &t[i], "name") == 0) {
+ /* We may additionally check if the value is either "true" or "false" */
+ printf ("- name: %.*s\n", t[i + 1].end - t[i + 1].start,
+ data + t[i + 1].start);
+ i++;
+ } else if (jsoneq (data, &t[i], "bustype") == 0) {
+ /* We may want to do strtol() here to get numeric value */
+ printf ("- bustype: %.*s\n", t[i + 1].end - t[i + 1].start,
+ data + t[i + 1].start);
+ i++;
+ } else if (jsoneq (data, &t[i], "manufacture_id") == 0) {
+ /* We may want to do strtol() here to get numeric value */
+ printf ("- manufacture_id: %.*s\n", t[i + 1].end - t[i + 1].start,
+ data + t[i + 1].start);
+ i++;
+ } else if (jsoneq (data, &t[i], "model_id") == 0) {
+ /* We may want to do strtol() here to get numeric value */
+ printf ("- model_id: %.*s\n", t[i + 1].end - t[i + 1].start,
+ data + t[i + 1].start);
+ i++;
+ } else if (jsoneq (data, &t[i], "total_size") == 0) {
+ /* We may want to do strtol() here to get numeric value */
+ printf ("- total_size: %.*s\n", t[i + 1].end - t[i + 1].start,
+ data + t[i + 1].start);
+ i++;
+ } else if (jsoneq (data, &t[i], "page_size") == 0) {
+ /* We may want to do strtol() here to get numeric value */
+ printf ("- page_size: %.*s\n", t[i + 1].end - t[i + 1].start,
+ data + t[i + 1].start);
+ i++;
+ } else if (jsoneq (data, &t[i], "feature_bits") == 0) {
+ int j;
+ printf ("- feature_bits:\n");
+ if (t[i + 1].type != JSMN_ARRAY) {
+ continue; /* We expect groups to be an array of strings */
+ }
+ for (j = 0; j < t[i + 1].size; j++) {
+ jsmntok_t *g = &t[i + j + 2];
+ printf (" * %.*s\n", g->end - g->start, data + g->start);
+ }
+ i += t[i + 1].size + 1;
+ } else if (jsoneq (data, &t[i], "tested") == 0) {
+ /* We may want to do strtol() here to get numeric value */
+ printf ("- tested: %.*s\n", t[i + 1].end - t[i + 1].start,
+ data + t[i + 1].start);
+ i++;
+ } else if (jsoneq (data, &t[i], "probe") == 0) {
+ /* We may want to do strtol() here to get numeric value */
+ printf ("- probe: %.*s\n", t[i + 1].end - t[i + 1].start,
+ data + t[i + 1].start);
+ i++;
+ } else if (jsoneq (data, &t[i], "probe_timing") == 0) {
+ /* We may want to do strtol() here to get numeric value */
+ printf ("- probe_timing: %.*s\n", t[i + 1].end - t[i + 1].start,
+ data + t[i + 1].start);
+ i++;
+ // .block_erasers =
+ // {
+ // {
+ // .eraseblocks = { {4 * 1024, 4096} },
+ // .block_erase = SPI_BLOCK_ERASE_20,
+ // }, {
+ // .eraseblocks = { {32 * 1024, 512} },
+ // .block_erase = SPI_BLOCK_ERASE_52,
+ // }, {
+ // .eraseblocks = { {64 * 1024, 256} },
+ // .block_erase = SPI_BLOCK_ERASE_D8,
+ // }, {
+ // .eraseblocks = { {16 * 1024 * 1024, 1}
+ //}, .block_erase = SPI_BLOCK_ERASE_60,
+ // }, {
+ // .eraseblocks = { {16 * 1024 * 1024, 1}
+ //}, .block_erase = SPI_BLOCK_ERASE_C7,
+ // }
+ // },
+ // } else if (jsoneq(data, &t[i], "block_erasers") == 0) {
+ // int j, k;
+ // printf("- block_erasers:\n");
+ // if (t[i + 1].type != JSMN_OBJECT) {
+ // continue; /* We expect groups to be an array of strings */
+ // }
+ // for (j = 0; j < t[i + 1].size; j++) {
+ // jsmntok_t *g = &t[i + j + 2];
+ // if (g[j + 1].type != JSMN_OBJECT) {
+ // continue;
+ // }
+ // for (k = 0; k < g[j + 1].size; k++) {
+ // jsmntok_t *h = &g[i + j + k + 2];
+ // printf(" * %.*s\n", h->end - h->start, data +
+ // h->start);
+ // }
+ // }
+ // i += t[i + 1].size + 1;
+ } else if (jsoneq (data, &t[i], "write") == 0) {
+ /* We may want to do strtol() here to get numeric value */
+ printf ("- write: %.*s\n", t[i + 1].end - t[i + 1].start,
+ data + t[i + 1].start);
+ i++;
+ } else if (jsoneq (data, &t[i], "read") == 0) {
+ /* We may want to do strtol() here to get numeric value */
+ printf ("- read: %.*s\n", t[i + 1].end - t[i + 1].start,
+ data + t[i + 1].start);
+ i++;
+ } else if (jsoneq (data, &t[i], "voltage") == 0) {
+ int j;
+ printf ("- voltage:\n");
+ if (t[i + 1].type != JSMN_ARRAY) {
+ continue; /* We expect groups to be an array of strings */
+ }
+ for (j = 0; j < t[i + 1].size; j++) {
+ jsmntok_t *g = &t[i + j + 2];
+ printf (" * %.*s\n", g->end - g->start, data + g->start);
+ }
+ i += t[i + 1].size + 1;
+ } else if (jsoneq (data, &t[i], "reg_bits") == 0) {
+ int j, k;
+ printf ("- reg_bits:\n");
+ if (t[i + 1].type != JSMN_OBJECT) {
+ continue; /* We expect reg_bits to be an object */
+ }
+ // printf("- ZZZ: %.*s\n", t[i + 1].end - t[i + 1].start,
+ // data + t[i + 1].start);
+ // for (j = 0; j < t[i + 1].size; j++) {
+ j = 0; // XXX
+ jsmntok_t *g = &t[i + j + 2];
+ // if (g[j + 1].type != JSMN_ARRAY) { // if the val at key g[j + 1]
+ //is not an array continue; continue;
+ // }
+ for (k = 0; k < g[j + 1].size; k++) {
+ printf ("X\n");
+ jsmntok_t *h = &g[k + 1]; // value of g[k] key.
+ if (h->type !=
+ JSMN_ARRAY) { // if the val at key g[k] is not an array continue;
+ printf ("Y\n");
+ continue;
+ }
+ if (jsoneq (data, &g[k], "srp") == 0) {
+ printf (" srp: %.*s\n", h->end - h->start, data + h->start);
+ } else if (jsoneq (data, &g[k], "srl") == 0) {
+ printf (" srl: %.*s\n", h->end - h->start, data + h->start);
+ } else if (jsoneq (data, &g[k], "tb") == 0) {
+ printf (" tb: %.*s\n", h->end - h->start, data + h->start);
+ } else if (jsoneq (data, &g[k], "sec") == 0) {
+ printf (" sec: %.*s\n", h->end - h->start, data + h->start);
+ } else if (jsoneq (data, &g[k], "cmp") == 0) {
+ printf (" cmp: %.*s\n", h->end - h->start, data + h->start);
+ } else if (jsoneq (data, &g[k], "wps") == 0) {
+ printf (" wps: %.*s\n", h->end - h->start, data + h->start);
+ } else {
+ printf (" <UNKNOWN>: %.*s\n", g[k].end - g[k].start,
+ data + g[k].start);
+ }
+ // TODO(handle bp) object.
+ // "bp" :
+ // {
+ // [STATUS1, 2, RW],
+ // [STATUS1, 3, RW],
+ // [STATUS1, 4, RW]
+ // },
+ }
+ //}
+ i += t[i + 1].size + 1;
+ } else if (jsoneq (data, &t[i], "decode_range") == 0) {
+ /* We may want to do strtol() here to get numeric value */
+ printf ("- decode_range: %.*s\n", t[i + 1].end - t[i + 1].start,
+ data + t[i + 1].start);
+ i++;
+ } else {
+ printf ("Unexpected key: %.*s\n", t[i].end - t[i].start,
+ data + t[i].start);
+ }
+ }
+
+ return EXIT_SUCCESS;
+}

To view, visit change 69610. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: If3e591468a60cb8846860e8b4ac1978b33f11aec
Gerrit-Change-Number: 69610
Gerrit-PatchSet: 1
Gerrit-Owner: Edward O'Callaghan <quasisec@chromium.org>
Gerrit-MessageType: newchange