|
| 1 | +#!/usr/bin/env python |
| 2 | + |
| 3 | +# |
| 4 | +# Copyright (C) 2018 Advanced Micro Devices, Inc. All rights reserved. |
| 5 | +# |
| 6 | +# The purpose of this script is to prepend a provided psp signature header to |
| 7 | +# a provided binary and update the psp header with the provided firmware |
| 8 | +# version and optionally type |
| 9 | +# The tool can also be used just to update an existing header |
| 10 | +# |
| 11 | + |
| 12 | +import sys |
| 13 | +import getopt |
| 14 | +import os |
| 15 | +import binascii |
| 16 | +from array import array |
| 17 | + |
| 18 | +HEADER_VERSION = 0x31534124 |
| 19 | +HEADER_VERSION_OFFSET_IN_BYTES = 0x10 |
| 20 | +SIZEFWSIGNED_HEADER_OFFSET_IN_BYTES = 0x14 |
| 21 | +SECURITY_PATCH_LEVEL_HEADER_OFFSET_IN_BYTES = 0x4C |
| 22 | +IMAGEVERSION_HEADER_OFFSET_IN_BYTES = 0x60 |
| 23 | +HEADER_SIZE_BYTES = 0x100 |
| 24 | + |
| 25 | +def main(argv): |
| 26 | + # Process the command line for the parameters for the build |
| 27 | + try: |
| 28 | + opts, args = getopt.getopt(argv, "i:v:s:o:", |
| 29 | + ["image=", "version=", "spl=", "output="]) |
| 30 | + except getopt.GetoptError: |
| 31 | + print("header_tool.py --image=<firmware image> --version=<firmware version> --spl=<spl version> --output=<output filename>") |
| 32 | + sys.exit(2) |
| 33 | + |
| 34 | + # Save the arguments |
| 35 | + for opt, arg in opts: |
| 36 | + if opt in ("-i", "--image"): |
| 37 | + image_filename = arg |
| 38 | + elif opt in ("-v", "--version"): |
| 39 | + version = arg |
| 40 | + elif opt in ("-o", "--output"): |
| 41 | + output_filename = arg |
| 42 | + elif opt in ("-s", "--spl"): |
| 43 | + spl = arg |
| 44 | + |
| 45 | + # Check that all parameters were correctly received |
| 46 | + try: |
| 47 | + image_filename |
| 48 | + version |
| 49 | + spl |
| 50 | + output_filename |
| 51 | + except NameError: |
| 52 | + print("header_tool.py --image=<firmware image> --version=<firmware version> --spl=<security patch level> --output=<output filename>") |
| 53 | + sys.exit(2) |
| 54 | + |
| 55 | + if os.path.isfile(image_filename) != True: |
| 56 | + print("header_tool.py ERROR: " + image_filename + " does not exist") |
| 57 | + sys.exit(2) |
| 58 | + |
| 59 | + image = array('I') |
| 60 | + input_file = open(image_filename, "rb") |
| 61 | + |
| 62 | + image.frombytes(input_file.read()) |
| 63 | + AmdSlSize = image[0] |
| 64 | + AmdSlSize = AmdSlSize >> 16 |
| 65 | + |
| 66 | + if (AmdSlSize % 16 != 0): |
| 67 | + AmdSlSize = AmdSlSize + (16 - (AmdSlSize % 16)) |
| 68 | + image[0] = image[0] & 0xFF |
| 69 | + image[0] = image[0] | (AmdSlSize << 16) |
| 70 | + |
| 71 | + if (os.path.getsize(image_filename) != (64 * 1024)): |
| 72 | + print("Error: AmdSL binary is not size is not equal to 64K ") |
| 73 | + |
| 74 | + AmdSlSizeInInt = AmdSlSize >> 2 |
| 75 | + |
| 76 | + # Store the ASCI of "$AS1" in header version |
| 77 | + image[AmdSlSizeInInt + int(HEADER_VERSION_OFFSET_IN_BYTES/4)] = HEADER_VERSION |
| 78 | + # Store the AmdSL Size |
| 79 | + image[AmdSlSizeInInt + int(SIZEFWSIGNED_HEADER_OFFSET_IN_BYTES/4)] = AmdSlSize |
| 80 | + image[AmdSlSizeInInt + int(IMAGEVERSION_HEADER_OFFSET_IN_BYTES/4)] = int(version, 16) |
| 81 | + image[AmdSlSizeInInt + int(SECURITY_PATCH_LEVEL_HEADER_OFFSET_IN_BYTES/4)] = int(spl, 16) |
| 82 | + |
| 83 | + # Since Input and output files may be the same close all files before doing output |
| 84 | + output_file = open(output_filename, "wb") |
| 85 | + |
| 86 | + # Write the output |
| 87 | + output_file.write(image) |
| 88 | + output_file.close() |
| 89 | + |
| 90 | + print("header_tool: completed successfully") |
| 91 | + |
| 92 | +if __name__ == "__main__": |
| 93 | + main(sys.argv[1:]) |
0 commit comments