ldr_config.py: better exception handling

This commit is contained in:
KazushiM
2022-02-25 11:22:14 +08:00
parent eaed085697
commit 4d76b83b95

View File

@@ -1,12 +1,11 @@
#!python #!python3
cust_conf = { cust_conf = {
# DRAM Timing: # DRAM Timing:
# 0: AUTO_ADJ_MARIKO_SAFE: Auto adjust timings for LPDDR4 ≤3733 Mbps specs, 8Gb density (Default). # 0: AUTO_ADJ_MARIKO_SAFE: Auto adjust timings for LPDDR4 ≤3733 Mbps specs, 8Gb density (Default).
# 1: AUTO_ADJ_MARIKO_4266: Auto adjust timings for LPDDR4X 4266 Mbps specs, 8Gb density. # 1: AUTO_ADJ_MARIKO_4266: Auto adjust timings for LPDDR4X 4266 Mbps specs, 8Gb density.
# 2: ENTIRE_TABLE_ERISTA: # 2: ENTIRE_TABLE_ERISTA:
# 3: ENTIRE_TABLE_MARIKO: Replace the entire max mtc table with customized one (provided by user). # 3: ENTIRE_TABLE_MARIKO: Replace the entire max mtc table with customized one (provided by user).
"mtcConf": 0, "mtcConf": 0,
# Mariko CPU: # Mariko CPU:
# - Max Clock in kHz: # - Max Clock in kHz:
# Default: 1785000 # Default: 1785000
@@ -14,13 +13,13 @@ cust_conf = {
# - Max Voltage in mV: # - Max Voltage in mV:
# Default voltage: 1120 # Default voltage: 1120
# Haven't tested anything higher than 1220. # Haven't tested anything higher than 1220.
"marikoCpuMaxClock": 2397000, "marikoCpuMaxClock": 2397000,
"marikoCpuMaxVolt": 1220, "marikoCpuMaxVolt": 1220,
# Mariko GPU: # Mariko GPU:
# - Max Clock in kHz: # - Max Clock in kHz:
# Default: 921600 # Default: 921600
# NVIDIA Maximum: 1267200 # NVIDIA Maximum: 1267200
"marikoGpuMaxClock": 1305600, "marikoGpuMaxClock": 1305600,
# Mariko EMC: # Mariko EMC:
# - RAM Clock in kHz: # - RAM Clock in kHz:
# Values should be > 1600000, and divided evenly by 9600. # Values should be > 1600000, and divided evenly by 9600.
@@ -30,14 +29,14 @@ cust_conf = {
# - System instabilities # - System instabilities
# - NAND corruption # - NAND corruption
# Timings from auto-adjustment have been tested safe for up to 1996.8 MHz for all DRAM chips. # Timings from auto-adjustment have been tested safe for up to 1996.8 MHz for all DRAM chips.
"marikoEmcMaxClock": 1996800, "marikoEmcMaxClock": 1996800,
# Erista CPU: # Erista CPU:
# Not tested and not enabled by default. # Not tested and not enabled by default.
# - Enable Overclock # - Enable Overclock
# Require modificaitions towards NewCpuTables! # Require modificaitions towards NewCpuTables!
# - Max Voltage in mV # - Max Voltage in mV
"eristaCpuOCEnable": 0, "eristaCpuOCEnable": 0,
"eristaCpuMaxVolt": 0, "eristaCpuMaxVolt": 0,
# Erista EMC: # Erista EMC:
# - RAM Clock in kHz # - RAM Clock in kHz
# [WARNING] # [WARNING]
@@ -50,30 +49,30 @@ cust_conf = {
# Value should be divided evenly by 12'500 # Value should be divided evenly by 12'500
# Default(HOS): 1125'000 # Default(HOS): 1125'000
# Not enabled by default. # Not enabled by default.
"eristaEmcMaxClock": 1862400, "eristaEmcMaxClock": 1862400,
"eristaEmcVolt": 0 "eristaEmcVolt": 0
} }
cust_range = {"mtcConf": (0, 3), cust_range = {
"marikoCpuMaxClock": (1785000, 3000000), "mtcConf": (0, 3),
"marikoCpuMaxVolt": (1100, 1300), "marikoCpuMaxClock": (1785000, 3000000),
"marikoGpuMaxClock": (768000, 1536000), "marikoCpuMaxVolt": (1100, 1300),
"marikoEmcMaxClock": (1612800, 2400000), "marikoGpuMaxClock": (768000, 1536000),
"eristaCpuMaxVolt": (1100, 1400), "marikoEmcMaxClock": (1612800, 2400000),
"eristaEmcMaxClock": (1600000, 2400000), "eristaCpuMaxVolt": (1100, 1400),
"eristaEmcVolt": (1100000, 1250000)} "eristaEmcMaxClock": (1600000, 2400000),
"eristaEmcVolt": (1100000, 1250000)
}
import struct import struct
import csv
from pprint import pprint
import argparse import argparse
cust_rev = 1 cust_rev = 1
cust_head = ["cust", "custRev"] cust_head = ["cust", "custRev"]
cust_body = ["mtcConf", cust_body = ["mtcConf",
"marikoCpuMaxClock", "marikoCpuMaxVolt", "marikoGpuMaxClock", "marikoEmcMaxClock", "marikoCpuMaxClock", "marikoCpuMaxVolt", "marikoGpuMaxClock", "marikoEmcMaxClock",
"eristaCpuOCEnable", "eristaCpuMaxVolt", "eristaEmcMaxClock", "eristaEmcVolt"] "eristaCpuOCEnable", "eristaCpuMaxVolt", "eristaEmcMaxClock", "eristaEmcVolt"]
cust_key = [*cust_head, *cust_body] cust_key = [*cust_head, *cust_body]
parser = argparse.ArgumentParser(description='Loader Configurator v'+str(cust_rev)) parser = argparse.ArgumentParser(description='Loader Configurator v'+str(cust_rev))
parser.add_argument("file", help="Path of loader.kip") parser.add_argument("file", help="Path of loader.kip")
@@ -81,84 +80,87 @@ parser.add_argument("--save", "-s", action="store_true", help="Save configuratio
parser.add_argument("--ignore", action="store_true", help="Ignore range safety check") parser.add_argument("--ignore", action="store_true", help="Ignore range safety check")
args = parser.parse_args() args = parser.parse_args()
def CSVRead(file_loc): def KIPCustParse(file_loc, conf_print=True) -> (int, dict):
with open(file_loc, 'r') as file: with open(file_loc, "rb") as file:
rd = csv.reader(file) header_str = b'KIP1Loader'
dct = {rows[0]:rows[1] for rows in rd} header = file.read(len(header_str))
file.close() file.seek(0)
return dct cust_magic = b'CUST'
cust_pos = file.read().find(cust_magic)
def CSVWrite(file_loc, dct): if header != header_str or cust_pos == -1:
with open(file_loc, 'w') as file: raise Exception("\n Invalid kip file!")
for key, value in dct.items():
file.write('{0},{1}\n'.format(key, value))
file.close()
def CustSafetyCheck(cust): file.seek(cust_pos)
warn_cnt = 0 cust_fmt = '<4s2H8I'
for i in cust_body: cust_size = struct.calcsize(cust_fmt)
val = int(cust[i]) cust_buf = file.read(cust_size)
if val and val not in range(*cust_range[i]): cust_val = struct.unpack(cust_fmt, cust_buf)
warn_cnt += 1 cust_dict = dict(zip(cust_key, cust_val))
print("[!] %s = %u (Expected range: %u ≤ value ≤ %u)" % (i, val, *cust_range[i]))
return warn_cnt
def KIPCustHandler(file_loc, cust={}): if cust_dict['custRev'] != cust_rev:
if len(cust) != 0: raise Exception(f"\n custRev does NOT match, expected: {cust_rev}, got: {cust_dict['custRev']}!")
missing = set(cust_body) - set(cust.keys())
[cust_dict.pop(key) for key in cust_head]
if conf_print:
print("Configuration from file")
[print(f"- {i:18s} : {cust_dict[i]:8d}") for i in cust_dict]
return (cust_pos, cust_dict)
def CustRangeCheck(cust):
range_error_str = ""
for i in cust_range:
val = int(cust[i])
if val and (val < cust_range[i][0] or val > cust_range[i][1]) :
range_error_str += f"\n- {i:18s} = {val:8d}, Expected range: {[*cust_range[i]]}"
if range_error_str:
raise ValueError(range_error_str)
def KIPCustSave(file_loc, cust_pos, cust_dict, range_check=True, cust_to_save={}):
missing = set(cust_body) - set(cust_to_save.keys())
if missing: if missing:
print("Invalid cust dict! Missing: %s" % missing) missing_str = "\n Invalid cust! Missing: "
return for i in missing:
if CustSafetyCheck(cust) and args.ignore == False: missing_str += f"\n- {i}"
return raise Exception(missing_str)
with open(file_loc, "rb") as file: if range_check:
header_str = b'KIP1Loader' CustRangeCheck(cust_to_save)
header = file.read(len(header_str))
file.seek(0)
cust_magic = b'CUST'
cust_pos = file.read().find(cust_magic)
if header != header_str or cust_pos == -1: diff_count = 0
print("Invalid kip file!") for i in cust_body:
return False diff_str = ""
if cust_dict[i] != cust_conf[i]:
diff_str = f"-> {cust_conf[i]:8d}"
diff_count += 1
print(f"- {i:18s} : {cust_dict[i]:8d} {diff_str}")
file.seek(cust_pos) if not diff_count:
cust_fmt = '<4s2H8I' print("Cust is identical, abort saving!")
cust_size = struct.calcsize(cust_fmt) return
cust_buf = file.read(cust_size)
cust_val = struct.unpack(cust_fmt, cust_buf)
cust_dict = dict(zip(cust_key, cust_val))
file.close()
if cust_dict['custRev'] != cust_rev: with open(file_loc, "rb+") as file:
print("custRev does NOT match, expected: %u, got: %u!" % (cust_rev, cust_dict['custRev'])) cust_head_fmt = '<4s1H'
return False cust_body_fmt = '<1H8I'
cust_bin = struct.pack(cust_body_fmt, *[cust_to_save[i] for i in cust_body])
file.seek(cust_pos + struct.calcsize(cust_head_fmt))
file.write(cust_bin)
if cust == {}:
[cust_dict.pop(key) for key in cust_head]
return cust_dict
with open(file_loc, "rb+") as file:
cust_head_fmt = '<4s1H'
cust_body_fmt = '<1H8I'
cust_bin = struct.pack(cust_body_fmt, *[cust[i] for i in cust_body])
file.seek(cust_pos + struct.calcsize(cust_head_fmt))
file.write(cust_bin)
file.close()
print("Done!") print("Done!")
def main(file_loc, save=False):
cust = KIPCustHandler(file_loc)
if not cust:
return
print("Configuration from file:")
pprint(cust, sort_dicts=False)
if save: def main(file_loc, ignore=False, save=False):
print("Saving new configuration...:") (cust_pos, cust_dict) = KIPCustParse(file_loc, conf_print=(not save))
pprint(cust_conf, sort_dicts=False)
KIPCustHandler(file_loc, cust_conf) if save:
print("Saving new configuration...")
KIPCustSave(file_loc, cust_pos, cust_dict, range_check=(not ignore), cust_to_save=cust_conf)
if __name__ == "__main__": if __name__ == "__main__":
main(args.file, args.save) main(args.file, args.ignore, args.save)