diff options
| author | Evan Lojewski <github@meklort.com> | 2020-10-09 23:12:57 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-09 23:12:57 -0600 |
| commit | e4ad1162e234603b37733bd54e80d8252b0bb5c4 (patch) | |
| tree | 1034ef439c576348d4e96fdca19f5acc5f6136d7 /utils/bcmflash/main.cpp | |
| parent | 52f2cfc67f912d0be7bef0511c0529159b65d779 (diff) | |
| download | bcm5719-ortega-e4ad1162e234603b37733bd54e80d8252b0bb5c4.tar.gz bcm5719-ortega-e4ad1162e234603b37733bd54e80d8252b0bb5c4.zip | |
bcmflash: Add ability to create full firmware images. (#135)
* bcmflash: Add ability to create full firmware images.
Co-authored-by: Richard Hughes <richard@hughsie.com>
Diffstat (limited to 'utils/bcmflash/main.cpp')
| -rw-r--r-- | utils/bcmflash/main.cpp | 136 |
1 files changed, 110 insertions, 26 deletions
diff --git a/utils/bcmflash/main.cpp b/utils/bcmflash/main.cpp index 791adb4..84858aa 100644 --- a/utils/bcmflash/main.cpp +++ b/utils/bcmflash/main.cpp @@ -413,6 +413,8 @@ int main(int argc, char const *argv[]) parser.add_option("-r", "restore").dest("restore").help("Update the target device to match the specified file.").metavar("FILE"); + parser.add_option("-c", "--create").dest("create").action("store_true").set_default("0").help("Create a full firmware image for use with fwupd."); + parser.add_option("-1", "--stage1").dest("stage1").help("Update the target with the specified stage1 image, if possible.").metavar("STAGE1"); parser.add_option("-a", "--ape").dest("ape").help("Update the target with the specified ape image, if possible.").metavar("APE"); @@ -428,8 +430,8 @@ int main(int argc, char const *argv[]) optparse::Values options = parser.parse_args(argc, argv); vector<string> args = parser.args(); - storage_t *target = NULL; + for (int i = 0; i < ARRAY_ELEMENTS(gStorage); i++) { if (gStorage[i].type == options["target_type"]) @@ -472,46 +474,128 @@ int main(int argc, char const *argv[]) } } - // Read the target file - nvram_size = target->size(target_name); - if (nvram_size > MAX_NVRAM_SIZE) + if (options.get("create")) { - cerr << "Unable to handle NVRAM size of " << nvram_size << " bytes."; - exit(-1); - } + // Default to erased flash contents. + memset(nvram.words, -1, sizeof(nvram.words)); - if (!target->read(target_name, nvram.bytes, nvram_size)) - { - cerr << "Unable to read nvram from target '" << options["target_type"] << ":" << target_name << "'" << endl; - exit(-1); - } + memcpy(nvram.contents.info.partNumber, "BCM95719", sizeof("BCM95719")); + memcpy(nvram.contents.info.partRevision, "A0", sizeof("A0")); + nvram.contents.info.vendorID = htobe16(0x14E4); + nvram.contents.info.deviceID = htobe16(0x1657); - if (options.is_set("restore")) - { - if (!bcmflash_file_read(options["restore"].c_str(), nvram.bytes, nvram_size)) + nvram.contents.header.magic = htobe32(BCM_NVRAM_MAGIC); + nvram.contents.header.bootstrapPhysAddr = htobe32(0x08003800); + nvram.contents.header.bootstrapOffset = htobe32(sizeof(NVRAMContents_t)); + nvram.contents.header.bootstrapWords = 0; + nvram.contents.header.crc = 0; + + if (options.is_set("stage1")) { - cerr << " Unable to open file '" << options["restore"] << "'" << endl; - exit(-1); + uint32_t new_stage1_length = bcmflash_file_size(options["stage1"].c_str()); + + if (new_stage1_length) + { + nvram.contents.header.bootstrapWords = htobe32(1 + ((new_stage1_length + 3) / 4)); + } + else + { + cerr << "Unable to open '" << options["stage1"] << "'." << endl; + exit(-1); + } } - cout << "Restoring from " << options["restore"] << " to '" << options["target_type"] << ":" << target_name << "'." << endl; + // now we know the size of stage1 + nvram.contents.header.crc = ~NVRam_crc((uint8_t *)&nvram.contents.header, sizeof(nvram.contents.header) - 4, 0xffffffff); + printf("CRC: %x\n", nvram.contents.header.crc); - target->write(target_name, nvram.bytes, nvram_size); - } + // Stage2 unsupported presently. + size_t stage1_length = (be32toh(nvram.contents.header.bootstrapWords) * 4) - 4; // last word is CRC + + uint32_t crc_word = stage1_length / 4; + stage1_wd = &nvram.words[be32toh(nvram.contents.header.bootstrapOffset) / 4]; + + uint32_t *stage2_wd = &stage1_wd[(crc_word + 1)]; // immediately after stage1 crc + NVRAMStage2_t *stage2 = (NVRAMStage2_t *)stage2_wd; + + stage2->header.magic = htobe32(BCM_NVRAM_MAGIC); + stage2->header.length = htobe32(4); /* CRC */ + stage2->words[0] = htobe32(0); + + // Invalidate all code directories + memset(nvram.contents.directory, 0, sizeof(nvram.contents.directory)); + + if (options.is_set("ape")) + { + uint32_t ape_length = bcmflash_file_size(options["ape"].c_str()); + + if (!ape_length) + { + cerr << "Unable to open '" << options["ape"] << "'." << endl; + exit(-1); + } + + // Allocate space for the code directory CRC. + ape_length += sizeof(uint32_t); + + uint32_t info = 0; + + ape_length = DIVIDE_RND_UP(ape_length, sizeof(uint32_t)); + info = BCM_CODE_DIRECTORY_SET_LENGTH(info, ape_length); + info = BCM_CODE_DIRECTORY_SET_CPU(info, BCM_CODE_DIRECTORY_CPU_APE); + info = BCM_CODE_DIRECTORY_SET_TYPE(info, 0); + nvram.contents.directory[0].codeInfo = htobe32(info); + nvram.contents.directory[0].codeAddress = htobe32(BCM_CODE_DIRECTORY_ADDR_APE); + nvram.contents.directory[0].directoryOffset = htobe32(4 * (&stage2->words[1] - nvram.words)); + + nvram_size = sizeof(uint32_t) * ((&stage2->words[1] - nvram.words) + ape_length); + } - if (options.is_set("backup")) + memset(&nvram.contents.vpd, 0, sizeof(nvram.contents.vpd)); + } + else { - if ("binary" == options["backup"]) + // Read the target file + nvram_size = target->size(target_name); + if (nvram_size > MAX_NVRAM_SIZE) + { + cerr << "Unable to handle NVRAM size of " << nvram_size << " bytes."; + exit(-1); + } + + if (!target->read(target_name, nvram.bytes, nvram_size)) { - // Save to file. - if (!bcmflash_file_write("firmware.fw", nvram.bytes, nvram_size)) + cerr << "Unable to read nvram from target '" << options["target_type"] << ":" << target_name << "'" << endl; + exit(-1); + } + + if (options.is_set("restore")) + { + if (!bcmflash_file_read(options["restore"].c_str(), nvram.bytes, nvram_size)) { + cerr << " Unable to open file '" << options["restore"] << "'" << endl; exit(-1); } + + cout << "Restoring from " << options["restore"] << " to '" << options["target_type"] << ":" << target_name << "'." << endl; + + target->write(target_name, nvram.bytes, nvram_size); } - else if ("extract" == options["backup"]) + + if (options.is_set("backup")) { - extract = true; + if ("binary" == options["backup"]) + { + // Save to file. + if (!bcmflash_file_write("firmware.fw", nvram.bytes, nvram_size)) + { + exit(-1); + } + } + else if ("extract" == options["backup"]) + { + extract = true; + } } } |

