summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2016-02-05 14:15:17 -0800
committerchrome-bot <chrome-bot@chromium.org>2016-02-08 12:09:06 -0800
commitd6c6dc51507d4eb5a1ac7a67920e5ab944e8b8b5 (patch)
tree27840127f12e1b42e05e401e2c39510fe7f0cd01
parentc1117fb707562886511d5ddd95fc0b1616eb3af8 (diff)
downloadchrome-ec-d6c6dc51507d4eb5a1ac7a67920e5ab944e8b8b5.tar.gz
cr50: signer: pick up latest and greatest
These are relevant changes in the FPGA tree since the most recent sync up. BRANCH=none BUG=chrome-os-partner:50141 TEST=image signed by the new signer boots successfully. Change-Id: Id30c5da614aa5c2496305f9687bce06030449beb Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/326483 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r--util/signer/codesigner.cc122
-rw-r--r--util/signer/common/image.h3
-rw-r--r--util/signer/image.cc19
3 files changed, 136 insertions, 8 deletions
diff --git a/util/signer/codesigner.cc b/util/signer/codesigner.cc
index 35056570fc..293490a9e2 100644
--- a/util/signer/codesigner.cc
+++ b/util/signer/codesigner.cc
@@ -76,7 +76,7 @@ xmlChar* get_val(xmlNodePtr node, const char* key) {
}
static
-bool print_fuse(xmlNodePtr a_node,
+bool get_fuse(xmlNodePtr a_node,
map<string, uint32_t>* ids, map<string, uint32_t>* bits) {
bool result = false;
@@ -123,7 +123,7 @@ bool find_fuses(xmlNodePtr a_node,
(content = xmlNodeGetContent(cur_node)) != NULL) {
if (!strcmp("FuseLogicalOffset", (const char*)content)) {
// Found a likely fuse definition section; collect it.
- done = print_fuse(a_node->parent->parent->parent, ids, bits);
+ done = get_fuse(a_node->parent->parent->parent, ids, bits);
}
}
@@ -195,6 +195,72 @@ bool readXML(const string& filename,
return result;
}
+// Write minified XML
+bool writeXML(const string& filename,
+ map<string, uint32_t>& ids,
+ map<string, uint32_t>& bits,
+ uint32_t p4cl) {
+ bool result = false;
+
+ // Get the names in order.
+ vector<string> names;
+ names.resize(ids.size());
+ for (map<string, uint32_t>::const_iterator it = ids.begin(); it != ids.end(); ++it) {
+ const string& name = it->first;
+ uint32_t offset = it->second;
+ names[offset] = name;
+ }
+
+ // Write out as nodes.
+ ofstream ofs(filename.c_str(), ofstream::out);
+ if (ofs) {
+ ofs << "<ArrayType>" << endl;
+ for (size_t i = 0; i < names.size(); ++i) {
+ const string& name = names[i];
+ ofs << "<ArrayItem>" << endl;
+ ofs << " <HashType>" << endl;
+ ofs << " <HashItem>" << endl;
+ ofs << " <Key>RegName</Key>" << endl;
+ ofs << " <Value>" << name << "</Value>" << endl;
+ ofs << " </HashItem>" << endl;
+ ofs << " <HashItem>" << endl;
+ ofs << " <Key>FuseLogicalOffset</Key>" << endl;
+ ofs << " <Value>" << i << "</Value>" << endl;
+ ofs << " </HashItem>" << endl;
+ ofs << " <HashItem>" << endl;
+ ofs << " <Key>Width</Key>" << endl;
+ ofs << " <Value>" << bits[name] << "</Value>" << endl;
+ ofs << " </HashItem>" << endl;
+ ofs << " </HashType>" << endl;
+ ofs << "</ArrayItem>" << endl;
+ }
+
+ // Write p4cl
+ ofs << "<ArrayItem>" << endl;
+ ofs << "<HashType>" << endl;
+ ofs << " <HashItem>" << endl;
+ ofs << " <Key>RegName</Key>" << endl;
+ ofs << " <Value>SWDP_P4_LAST_SYNC</Value>" << endl;
+ ofs << " </HashItem>" << endl;
+ ofs << " <HashItem>" << endl;
+ ofs << " <Key>Default</Key>" << endl;
+ ofs << " <Value>" << p4cl << "</Value>" << endl;
+ ofs << " </HashItem>" << endl;
+ // Write fake offset to make parser happy
+ ofs << " <HashItem>" << endl;
+ ofs << " <Key>FuseLogicalOffset</Key>" << endl;
+ ofs << " <Value>0</Value>" << endl;
+ ofs << " </HashItem>" << endl;
+ ofs << "</HashType>" << endl;
+ ofs << "</ArrayItem>" << endl;
+
+ ofs << "</ArrayType>" << endl;
+
+ result = true;
+ }
+
+ return result;
+}
// Read JSON, populate map, name -> val
bool readJSON(const string& filename,
@@ -233,19 +299,19 @@ bool readJSON(const string& filename,
#define GETVALUE(x) do { \
if (!d.HasMember(x)){FATAL("manifest is lacking field '%s'\n", x);}; \
- values->insert(make_pair(x, d[x].GetInt())); \
+ (*values)[x] = d[x].GetInt(); \
} while (0)
CHECKVALUE("fuses");
const rapidjson::Document::ValueType& fuses = d["fuses"];
for (rapidjson::Value::ConstMemberIterator it = fuses.MemberBegin(); it != fuses.MemberEnd(); ++it) {
- fusemap->insert(make_pair(it->name.GetString(), it->value.GetInt()));
+ (*fusemap)[it->name.GetString()] = it->value.GetInt();
}
CHECKVALUE("info");
const rapidjson::Document::ValueType& infos = d["info"];
for (rapidjson::Value::ConstMemberIterator it = infos.MemberBegin(); it != infos.MemberEnd(); ++it) {
- infomap->insert(make_pair(it->name.GetString(), it->value.GetInt()));
+ (*infomap)[it->name.GetString()] = it->value.GetInt();
}
GETVALUE("keyid");
@@ -282,6 +348,10 @@ string jsonFilename;
string outputFormat;
string signatureFilename;
string hashesFilename;
+bool fillPattern = false;
+uint32_t pattern = -1;
+bool fillRandom = false;
+string xmlOutputFilename;
void usage(int argc, char* argv[]) {
fprintf(stderr, "Usage: %s options\n"
@@ -293,6 +363,9 @@ void usage(int argc, char* argv[]) {
"[--format=bin|hex] output file format, hex is default\n"
"[--signature=$sig-filename] replace signature with file content\n"
"[--hashes=$hashes-filename] destination file for intermediary hashes to be signed\n"
+ "[--randomfill] to pad image to 512K with random bits\n"
+ "[--patternfill=N] to pad image to 512K with pattern N\n"
+ "[--writefuses=$xml-filename] to write out shortened xml\n"
"[--verbose]\n",
argv[0]);
}
@@ -310,11 +383,14 @@ int getOptions(int argc, char* argv[]) {
{"xml", required_argument, NULL, 'x'},
{"signature", required_argument, NULL, 's'},
{"hashes", required_argument, NULL, 'H'},
+ {"randomfill", no_argument, NULL, 'r'},
+ {"patternfill", required_argument, NULL, 'p'},
+ {"writefuses", required_argument, NULL, 'w'},
{0, 0, 0, 0}
};
int c, option_index = 0;
outputFormat.assign("hex");
- while ((c = getopt_long(argc, argv, "i:o:k:x:j:f:s:H:hv",
+ while ((c = getopt_long(argc, argv, "i:o:p:k:x:j:f:s:H:w:hvr",
long_options, &option_index)) != -1) {
switch (c) {
case 0:
@@ -334,6 +410,9 @@ int getOptions(int argc, char* argv[]) {
case 'x':
xmlFilename.assign(optarg);
break;
+ case 'w':
+ xmlOutputFilename.assign(optarg);
+ break;
case 's':
signatureFilename.assign(optarg);
break;
@@ -346,9 +425,17 @@ int getOptions(int argc, char* argv[]) {
case 'H':
hashesFilename.assign(optarg);
break;
+ case 'r':
+ fillRandom = true;
+ break;
+ case 'p':
+ fillPattern = true;
+ pattern = strtoul(optarg, NULL, 0);
+ break;
case 'h':
usage(argc, argv);
return 1;
+
case 'v':
FLAGS_verbose = true;
break;
@@ -379,6 +466,9 @@ int main(int argc, char* argv[]) {
Image image;
if (!image.fromElf(inputFilename)) return -2;
+ if (fillPattern) image.fillPattern(pattern);
+ if (fillRandom) image.fillRandom();
+
SignedHeader hdr;
hdr.keyid = key.n0inv();
@@ -402,6 +492,9 @@ int main(int argc, char* argv[]) {
values.insert(make_pair("epoch", 0x1337));
}
+ // Hardcoded expectation. Can be overwritten in JSON w/ new explicit value.
+ fuses["FW_DEFINED_DATA_EXTRA_BLK6"] = 0;
+
if (!jsonFilename.empty() &&
!readJSON(jsonFilename, &tag, &values, &fuses, &infos)) {
FATAL("Failed to read JSON from '%s'\n", jsonFilename.c_str());
@@ -457,11 +550,28 @@ int main(int argc, char* argv[]) {
VERBOSE("found %lu fuse definitions\n", fuse_ids.size());
assert(fuse_ids.size() < FUSE_MAX);
+ if (fuse_ids.size() != 0) {
+ // Make sure FW_DEFINED_DATA_EXTRA_BLK6 is still at 125, width 3.
+ assert(fuse_ids["FW_DEFINED_DATA_EXTRA_BLK6"] == 125);
+ assert(fuse_bits["FW_DEFINED_DATA_EXTRA_BLK6"] == 5);
+ }
+
+ // Whether we loaded xml or not, hardcode FW_DEFINED_DATA_EXTRA_BLK6
+ fuse_ids["FW_DEFINED_DATA_EXTRA_BLK6"] = 125;
+ fuse_bits["FW_DEFINED_DATA_EXTRA_BLK6"] = 5;
+
for (map<string, uint32_t>::const_iterator it = fuse_ids.begin(); it != fuse_ids.end(); ++it) {
VERBOSE("fuse '%s' at %u, width %u\n",
it->first.c_str(), it->second, fuse_bits[it->first]);
}
+ // Write condensed XML if asked to.
+ if (!xmlOutputFilename.empty()) {
+ writeXML(xmlOutputFilename,
+ fuse_ids,
+ fuse_bits,
+ xml_p4cl);
+ }
// Compute fuse_values array, according to manifest and xml.
uint32_t fuse_values[FUSE_MAX];
diff --git a/util/signer/common/image.h b/util/signer/common/image.h
index ebf0c5d838..c7e04a2753 100644
--- a/util/signer/common/image.h
+++ b/util/signer/common/image.h
@@ -41,6 +41,9 @@ class Image {
int ro_max() const { return ro_max_; }
int rx_max() const { return rx_max_; }
+ void fillPattern(uint32_t);
+ void fillRandom();
+
private:
void toIntelHex(FILE *fout) const;
int nibble(char n);
diff --git a/util/signer/image.cc b/util/signer/image.cc
index cd1baef85e..7945bf88d8 100644
--- a/util/signer/image.cc
+++ b/util/signer/image.cc
@@ -163,8 +163,8 @@ bool Image::fromElf(const string& filename) {
if (phdr.p_paddr < ro_base_) {
ro_base_ = phdr.p_paddr;
}
- if (phdr.p_paddr + phdr.p_memsz > ro_max_) {
- ro_max_ = phdr.p_paddr + phdr.p_memsz;
+ if (phdr.p_paddr + phdr.p_filesz > ro_max_) {
+ ro_max_ = phdr.p_paddr + phdr.p_filesz;
}
// Copy data into image
@@ -326,6 +326,21 @@ void Image::toIntelHex(FILE *fout) const {
}
}
+void Image::fillPattern(uint32_t pattern) {
+ for (int i = high_ - base_; i < 512*1024 - 2048; i += 4) {
+ *(uint32_t*)(mem_ + i) = pattern;
+ }
+ high_ = 512 * 1024 - 2048;
+}
+
+void Image::fillRandom() {
+ srand(time(NULL));
+ for (int i = high_ - base_; i < 512*1024 - 2048; i += 4) {
+ *(uint32_t*)(mem_ + i) = rand();
+ }
+ high_ = 512 * 1024 - 2048;
+}
+
void Image::generate(const std::string& filename, bool hex_output) const {
FILE* fout = fopen(filename.c_str(), "w");
if (!fout) return;