diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2016-02-05 14:15:17 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-02-08 12:09:06 -0800 |
commit | d6c6dc51507d4eb5a1ac7a67920e5ab944e8b8b5 (patch) | |
tree | 27840127f12e1b42e05e401e2c39510fe7f0cd01 /util | |
parent | c1117fb707562886511d5ddd95fc0b1616eb3af8 (diff) | |
download | chrome-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>
Diffstat (limited to 'util')
-rw-r--r-- | util/signer/codesigner.cc | 122 | ||||
-rw-r--r-- | util/signer/common/image.h | 3 | ||||
-rw-r--r-- | util/signer/image.cc | 19 |
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; |