diff options
Diffstat (limited to 'chip/mec1322/util/pack_ec.py')
-rwxr-xr-x | chip/mec1322/util/pack_ec.py | 116 |
1 files changed, 77 insertions, 39 deletions
diff --git a/chip/mec1322/util/pack_ec.py b/chip/mec1322/util/pack_ec.py index 6039b3c10b..46aebe5564 100755 --- a/chip/mec1322/util/pack_ec.py +++ b/chip/mec1322/util/pack_ec.py @@ -5,30 +5,19 @@ # found in the LICENSE file. # A script to pack EC binary into SPI flash image for MEC1322 +# Based on MEC1322_ROM_Doc_Rev0.5.pdf. -# TODO(crosbug.com/p/24107): Add reference to document on image format. - +import argparse import hashlib import os import struct import subprocess import tempfile -# TODO(crosbug.com/p/24188): Make these options available as command line -# arguments. -SPI_SIZE = 4 * 1024 * 1024 -HEADER_PEM_FILE = 'rsakey_sign_header.pem' -PAYLOAD_PEM_FILE = 'rsakey_sign_payload.pem' -PAYLOAD_FILE = 'ec.bin' # Set to 'ec.RO.flat' for RO-only image -HEADER_LOCATION = 0x170000 -HEADER_FLAG1 = 0x00 -HEADER_FLAG2 = 0x01 -SPI_READ_CMD = 0x01 LOAD_ADDR = 0x100000 -SPI_CHIP_SELECT = 0 HEADER_SIZE = 0x140 -PAYLOAD_OFFSET = 0x240 -OUTPUT_FILE = 'ec.4mb.bin' +SPI_CLOCK_LIST = [48, 24, 12, 8] +SPI_READ_CMD_LIST = [0x3, 0xb, 0x3b] CRC_TABLE = [0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d] @@ -77,20 +66,35 @@ def GetPublicKey(pem_file): modulus_raw[0:256]))) return struct.pack('<Q', exp), modulus +def GetSpiClockParameter(args): + assert args.spi_clock in SPI_CLOCK_LIST, \ + "Unsupported SPI clock speed %d MHz" % args.spi_clock + return SPI_CLOCK_LIST.index(args.spi_clock) + +def GetSpiReadCmdParameter(args): + assert args.spi_read_cmd in SPI_READ_CMD_LIST, \ + "Unsupported SPI read command 0x%x" % args.spi_read_cmd + return SPI_READ_CMD_LIST.index(args.spi_read_cmd) + def PadZeroTo(data, size): data.extend('\0' * (size - len(data))) -def BuildHeader(payload_len): +def BuildHeader(args, payload_len): + # Identifier and header version header = bytearray(['C', 'S', 'M', 'S', '\0']) - header.extend([HEADER_FLAG1, HEADER_FLAG2, SPI_READ_CMD]) + + PadZeroTo(header, 0x6) + header.append(GetSpiClockParameter(args)) + header.append(GetSpiReadCmdParameter(args)) + header.extend(struct.pack('<I', LOAD_ADDR)) - header.extend(struct.pack('<I', GetEntryPoint(PAYLOAD_FILE))) + header.extend(struct.pack('<I', GetEntryPoint(args.input))) header.append((payload_len >> 6) & 0xff) header.append((payload_len >> 14) & 0xff) PadZeroTo(header, 0x14) - header.extend(struct.pack('<I', PAYLOAD_OFFSET)) + header.extend(struct.pack('<I', args.payload_offset)) - exp, modulus = GetPublicKey(PAYLOAD_PEM_FILE) + exp, modulus = GetPublicKey(args.payload_key) PadZeroTo(header, 0x20) header.extend(exp) PadZeroTo(header, 0x30) @@ -114,36 +118,70 @@ def SignByteArray(data, pem_file): signed.reverse() return bytearray(''.join(signed)) -def BuildTag(header_loc): - tag = bytearray([(header_loc >> 8) & 0xff, - (header_loc >> 16) & 0xff, - (header_loc >> 24) & 0xff]) - if SPI_CHIP_SELECT != 0: +def BuildTag(args): + tag = bytearray([(args.header_loc >> 8) & 0xff, + (args.header_loc >> 16) & 0xff, + (args.header_loc >> 24) & 0xff]) + if args.chip_select != 0: tag[2] |= 0x80 tag.append(Crc8(0, tag)) return tag def main(): + parser = argparse.ArgumentParser() + parser.add_argument("-i", "--input", + help="EC binary to pack, usually ec.bin or ec.RO.flat.", + metavar="EC_BIN", default="ec.bin") + parser.add_argument("-o", "--output", + help="Output flash binary file", + metavar="EC_SPI_FLASH", default="ec.packed.bin") + parser.add_argument("--header_key", + help="PEM key file for signing header", + default="rsakey_sign_header.pem") + parser.add_argument("--payload_key", + help="PEM key file for signing payload", + default="rsakey_sign_payload.pem") + parser.add_argument("-s", "--spi_size", type=int, + help="Size of the SPI flash in MB", + default=4) + parser.add_argument("-l", "--header_loc", type=int, + help="Location of header in SPI flash", + default=0x170000) + parser.add_argument("-p", "--payload_offset", type=int, + help="The offset of payload from the header", + default=0x240) + parser.add_argument("-c", "--chip_select", type=int, + help="Chip select signal to use, either 0 or 1.", + default=0) + parser.add_argument("--spi_clock", type=int, + help="SPI clock speed. 8, 12, 24, or 48 MHz.", + default=24) + parser.add_argument("--spi_read_cmd", type=int, + help="SPI read command. 0x3, 0xB, or 0x3B.", + default=0xb) + args = parser.parse_args() + + spi_size = args.spi_size * 1024 * 1024 spi_list = [] - payload = GetPayload(PAYLOAD_FILE) + payload = GetPayload(args.input) payload_len = len(payload) - payload_signature = SignByteArray(payload, PAYLOAD_PEM_FILE) - header = BuildHeader(payload_len) - header_signature = SignByteArray(header, HEADER_PEM_FILE) - tag = BuildTag(HEADER_LOCATION) - - spi_list.append((HEADER_LOCATION, header)) - spi_list.append((HEADER_LOCATION + HEADER_SIZE, header_signature)) - spi_list.append((HEADER_LOCATION + PAYLOAD_OFFSET, payload)) - spi_list.append((HEADER_LOCATION + PAYLOAD_OFFSET + payload_len, + payload_signature = SignByteArray(payload, args.payload_key) + header = BuildHeader(args, payload_len) + header_signature = SignByteArray(header, args.header_key) + tag = BuildTag(args) + + spi_list.append((args.header_loc, header)) + spi_list.append((args.header_loc + HEADER_SIZE, header_signature)) + spi_list.append((args.header_loc + args.payload_offset, payload)) + spi_list.append((args.header_loc + args.payload_offset + payload_len, payload_signature)) - spi_list.append((SPI_SIZE - 256, tag)) + spi_list.append((spi_size - 256, tag)) spi_list = sorted(spi_list) - with open(OUTPUT_FILE, 'wb') as f: + with open(args.output, 'wb') as f: addr = 0 for s in spi_list: assert addr <= s[0] @@ -152,8 +190,8 @@ def main(): addr = s[0] f.write(s[1]) addr += len(s[1]) - if addr < SPI_SIZE: - f.write('\xff' * (SPI_SIZE - addr)) + if addr < spi_size: + f.write('\xff' * (spi_size - addr)) if __name__ == '__main__': main() |