summaryrefslogtreecommitdiff
path: root/util/cbi-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/cbi-util.c')
-rw-r--r--util/cbi-util.c72
1 files changed, 68 insertions, 4 deletions
diff --git a/util/cbi-util.c b/util/cbi-util.c
index 54782f8bad..fe0c4c2bce 100644
--- a/util/cbi-util.c
+++ b/util/cbi-util.c
@@ -40,6 +40,7 @@ enum {
OPT_FW_CONFIG,
OPT_PCB_SUPPLIER,
OPT_SSFC,
+ OPT_REWORK_ID,
OPT_SIZE,
OPT_ERASE_BYTE,
OPT_SHOW_ALL,
@@ -57,6 +58,7 @@ static const struct option opts_create[] = {
{"fw_config", 1, 0, OPT_FW_CONFIG},
{"pcb_supplier", 1, 0, OPT_PCB_SUPPLIER},
{"ssfc", 1, 0, OPT_SSFC},
+ {"rework_id", 1, 0, OPT_REWORK_ID},
{"size", 1, 0, OPT_SIZE},
{"erase_byte", 1, 0, OPT_ERASE_BYTE},
{NULL, 0, 0, 0}
@@ -79,6 +81,7 @@ static const char *field_name[] = {
"FW_CONFIG",
"PCB_SUPPLIER",
"SSFC",
+ "REWORK_ID",
};
BUILD_ASSERT(ARRAY_SIZE(field_name) == CBI_TAG_COUNT);
@@ -101,9 +104,11 @@ const char help_create[] =
" --fw_config <value> Firmware configuration bit-field\n"
" --pcb_supplier <value> PCB supplier\n"
" --ssfc <value> Second Source Factory Cache bit-field\n"
+ " --rework_id <lvalue> REWORK_ID\n"
"\n"
- "<value> must be a positive integer <= 0XFFFFFFFF and field size can\n"
- " be optionally specified by <value:size> notation: e.g. 0xabcd:4.\n"
+ "<value> must be a positive integer <= 0XFFFFFFFF, <lvalue> must be a\n"
+ " positive integer <= 0xFFFFFFFFFFFFFFFF and field size can be\n"
+ " optionally specified by <value:size> notation: e.g. 0xabcd:4.\n"
"<size> must be a positive integer <= 0XFFFF.\n"
"<string> is a string\n"
"\n";
@@ -124,6 +129,11 @@ struct integer_field {
int size;
};
+struct long_integer_field {
+ uint64_t val;
+ int size;
+};
+
static void print_help_create(void)
{
printf(help_create, cmd_name);
@@ -250,6 +260,48 @@ static int parse_integer_field(const char *arg, struct integer_field *f)
return 0;
}
+static int parse_uint64_field(const char *arg, struct long_integer_field *f)
+{
+ uint64_t val;
+ char *e;
+ char *ch;
+
+ val = strtoul(arg, &e, 0);
+ /* strtoul sets an errno for invalid input. If the value read is out of
+ * range of representable values by an unsigned long int, the function
+ * returns ULONG_MAX or ULONG_MIN and the errno is set to ERANGE.
+ */
+ if (errno == ERANGE || !*arg || (e && *e && *e != ':')) {
+ fprintf(stderr, "Invalid integer value\n");
+ return -1;
+ }
+ f->val = val;
+
+ ch = strchr(arg, ':');
+ if (ch) {
+ ch++;
+ val = strtoul(ch, &e, 0);
+ if (val < 1 || 8 < val || !*ch || (e && *e)) {
+ fprintf(stderr, "Invalid size suffix\n");
+ return -1;
+ }
+ f->size = val;
+ } else {
+ if (f->val < UINT32_MAX)
+ f->size = estimate_field_size(f->val);
+ else
+ f->size = 8; /* assign default long int size */
+ }
+
+ if (f->size < 8 && (f->val > (1ull << f->size * 8))) {
+ fprintf(stderr, "Value (0x%llx) exceeds field size (%d)\n",
+ (unsigned long long)f->val, f->size);
+ return -1;
+ }
+
+ return 0;
+}
+
static int cmd_create(int argc, char **argv)
{
uint8_t *cbi;
@@ -261,6 +313,7 @@ static int cmd_create(int argc, char **argv)
struct integer_field fw_config;
struct integer_field pcb_supplier;
struct integer_field ssfc;
+ struct long_integer_field rework;
const char *dram_part_num;
const char *oem_name;
} bi;
@@ -341,6 +394,10 @@ static int cmd_create(int argc, char **argv)
if (parse_integer_field(optarg, &bi.ssfc))
return -1;
break;
+ case OPT_REWORK_ID:
+ if (parse_uint64_field(optarg, &bi.rework))
+ return -1;
+ break;
}
}
@@ -372,6 +429,7 @@ static int cmd_create(int argc, char **argv)
p = cbi_set_data(p, CBI_TAG_PCB_SUPPLIER, &bi.pcb_supplier.val,
bi.pcb_supplier.size);
p = cbi_set_data(p, CBI_TAG_SSFC, &bi.ssfc.val, bi.ssfc.size);
+ p = cbi_set_data(p, CBI_TAG_REWORK_ID, &bi.rework.val, bi.rework.size);
p = cbi_set_string(p, CBI_TAG_DRAM_PART_NUM, bi.dram_part_num);
p = cbi_set_string(p, CBI_TAG_OEM_NAME, bi.oem_name);
@@ -407,7 +465,8 @@ static void print_string(const uint8_t *buf, enum cbi_data_tag tag)
static void print_integer(const uint8_t *buf, enum cbi_data_tag tag)
{
- uint32_t v;
+ uint64_t v;
+
struct cbi_data *d = cbi_find_tag(buf, tag);
const char *name;
@@ -426,12 +485,16 @@ static void print_integer(const uint8_t *buf, enum cbi_data_tag tag)
case 4:
v = *(uint32_t *)d->value;
break;
+ case 8:
+ v = *(uint64_t *)d->value;
+ break;
default:
printf(" %s: Integer of size %d not supported\n",
name, d->size);
return;
}
- printf(" %s: %u (0x%x, %u, %u)\n", name, v, v, d->tag, d->size);
+ printf(" %s: %llu (0x%llx, %u, %u)\n", name, (unsigned long long)v,
+ (unsigned long long)v, d->tag, d->size);
}
static int cmd_show(int argc, char **argv)
@@ -500,6 +563,7 @@ static int cmd_show(int argc, char **argv)
print_integer(buf, CBI_TAG_FW_CONFIG);
print_integer(buf, CBI_TAG_PCB_SUPPLIER);
print_integer(buf, CBI_TAG_SSFC);
+ print_integer(buf, CBI_TAG_REWORK_ID);
print_string(buf, CBI_TAG_DRAM_PART_NUM);
print_string(buf, CBI_TAG_OEM_NAME);