Files
amlogic/source/bootrom_emulator/tools.py
Eljakim Herrewijnen 0980476603 initial
2024-03-30 21:13:26 +01:00

242 lines
7.3 KiB
Python

import struct
import sys, os, pathlib, struct, time, io, tqdm, logging
import string
import typing
SUCCESS_STATUS = 0
ERROR_STATUS = 4
KB = 1024
MB = KB * 1024
GB = MB * 1024
TB = GB * 1024
PB = TB * 1024
COLOR_PURPLE = '\033[95m'
COLOR_BLUE = '\033[94m'
COLOR_LBLUE = '\033[96m'
COLOR_GREEN = '\033[92m'
COLOR_YELLOW = '\033[93m'
COLOR_RED = '\033[91m'
COLOR_END = '\033[0m'
COLOR_BOLD = '\033[1m'
COLOR_UNDERLINE = '\033[4m'
# Python 2 support
try:
input = raw_input
except NameError:
pass
def info(msg):
print("[\033[34;1mi\033[0m] %s" % (msg))
def ok(msg):
print("[\033[32;1m+\033[0m] %s" % (msg))
def warn(msg):
print("[\033[33;1mw\033[0m] %s" % (msg))
def error(msg):
print("[\033[31;1m!\033[0m] %s" % (msg))
def p64(val):
return struct.pack("<Q", val)
def bytes_len_hex(inbytes, str_len):
return (inbytes[str_len:], inbytes[:str_len].encode("hex"))
def bytes_len(inbytes, str_len):
return (inbytes[str_len:], inbytes[:str_len])
def utf16_str(inbytes, str_len):
data = inbytes[:str_len]
stri = ""
for i in range(0, len(data), 2):
if data[i] == "\x00":
break
stri += data[i]
return (inbytes[str_len:], stri)
def str_len(inbytes, str_len):
return (inbytes[str_len:], inbytes[:str_len].split("\x00")[0])
def u64(inbytes):
return struct.unpack("<Q", inbytes[:8])[0]
# return (inbytes[8:], struct.unpack("<Q", inbytes[:8])[0])
def u32(s):
"""u32(s) -> int
Unpack 32 bits integer from a little endian str representation
"""
return struct.unpack('<I', s)[0]
def u16(inbytes):
return struct.unpack("<H", inbytes[:2])[0]
return (inbytes[2:], struct.unpack("<H", inbytes[:2])[0])
def u8(inbytes):
return ord(inbytes[:1])
# return (inbytes[1:], ord(inbytes[:1]))
def p32(i):
"""p32(i) -> str
Pack 32 bits integer (little endian)
"""
return struct.pack('<I', i)
def round_down(address, align):
"""round_down(address, align) -> int
Round down ``address`` to the nearest increment of ``align``.
"""
return address & ~(align-1)
def page_align(address):
"""page_align(address) -> int
Round down ``address`` to the nearest page boundary.
"""
return round_down(address, 0x1000)
def align_top(address, align):
"""page_align_up(address) -> int
Round up ``address`` to the nearest page boundary.
"""
return round_down(address + align, align)
def page_align_top(address):
"""page_align_up(address) -> int
Round up ``address`` to the nearest page boundary.
"""
return round_down(address + 0x1000, 0x1000)
def util_get_mmu_entry(base, address):
# May not work on other SDM
# work only for level 1
return base + 8 * (0x200 + ((page_align(address) >> 12) & 0x1FF))
def simple_hexdump(src, length=16, sep='.', start = 0):
FILTER = ''.join([(len(repr(chr(x))) == 3) and chr(x) or sep for x in range(256)])
lines = []
for c in range(0, len(src), length):
chars = src[c:c+length]
hexstr = ' '.join(["%02x" % ord(x) for x in chars]) if type(chars) is str else ' '.join(['{:02x}'.format(x) for x in chars])
if len(hexstr) > 24:
hexstr = "%s %s" % (hexstr[:24], hexstr[24:])
printable = ''.join(["%s" % ((ord(x) <= 127 and FILTER[ord(x)]) or sep) for x in chars]) if type(chars) is str else ''.join(['{}'.format((x <= 127 and FILTER[x]) or sep) for x in chars])
lines.append("%08x: %-*s |%s|" % (c + start, length*3, hexstr, printable))
return lines
def print_addr64(addr : bytes):
print(hex(struct.unpack("<Q", addr)[0]))
def hexdump(buf, title="", color=6, start=0, remove_dup=True):
color_start = "\033[3%d;1m" % color
color_start_no_bold = "\033[0m\033[3%dm" % color
color_stop = "\033[0m"
address_format_size = len("0x%08x " % (len(buf) + start))
space_before = " "*address_format_size
out=("%s%s"+""*49+""+""*18+"%s\n") % (space_before, color_start,color_stop)
if title != "":
dashlen = int((46-len(title))/2)
out=("%s%s"+""*dashlen+" "+title+" "+""*(dashlen-(1-(len(title)%2)))+""+""*18+"%s\n") % (space_before, color_start,color_stop)
last_is_dup = False
for i in range(0,len(buf),16):
if remove_dup:
if i != 0 and (i+16) < len(buf):
if buf[i:i+16] == buf[i-16:i] and buf[i:i+16] == buf[i+16:i+32]:
if not last_is_dup:
out+="%s%s* ┆ %s" % (space_before[:-2], color_start, color_start_no_bold)
out+=""*47
out+="%s%s" % (color_start, color_start_no_bold)
out+=""*16
out+=" %s%s\n" % (color_start, color_stop)
last_is_dup = True
continue
else:
last_is_dup=False
out+="%s0x%08x%s" % (color_start,i+start,color_stop)
for j in range(16):
if i+j < len(buf):
if type(buf) == bytes:
out+="%02x " % (buf[i+j])
else:
out+="%02x " % (ord(buf[i+j]))
else:
out+=" "
out+="%s%s" % (color_start,color_stop)
for j in range(16):
if i+j < len(buf):
char = buf[i+j]
if type(char) == int:
char = chr(char)
if char in string.printable and char not in "\t\n\r\x0b\x0c":
out+="%s" % (char)
else:
out+="."
else:
out+=" "
out+=" %s%s\n" % (color_start,color_stop)
out+=("%s%s"+""*49+""+""*18+"%s") % (space_before, color_start,color_stop)
print(out)
def confirm(message):
"""
Ask user to enter Y or yes (case-insensitive).
"""
answer = ""
while answer not in ["yes", "y", 'ye', 'yeah', 'go']:
answer = input(message).lower()
return answer
if __name__ == "__main__":
print(f"{COLOR_BLUE}BLUE{COLOR_END}")
print(f"{COLOR_PURPLE}PURPLE{COLOR_END}")
print(f"{COLOR_LBLUE}LBLUE{COLOR_END}")
print(f"{COLOR_GREEN}GREEN{COLOR_END}")
print(f"{COLOR_YELLOW}YELLOW{COLOR_END}")
print(f"{COLOR_RED}RED{COLOR_END}")
print(f"{COLOR_BOLD}BOLD{COLOR_END}")
print(f"{COLOR_UNDERLINE}UNDERLINE{COLOR_END}")
class CustomFormatter(logging.Formatter):
"""Logging Formatter to add colors and count warning / errors"""
grey = "\x1b[38;20m"
yellow = "\x1b[33;20m"
blue = "\x1b[36;20m"
green = "\x1b[32;20m"
red = "\x1b[31;20m"
bold_red = "\x1b[31;1m"
reset = "\x1b[0m"
format = "%(name)s | %(levelname)s | %(message)s" # (%(filename)s:%(lineno)d)"
FORMATS = {
logging.DEBUG: green + format + reset,
logging.INFO: blue + format + reset,
logging.WARNING: yellow + format + reset,
logging.ERROR: red + format + reset,
}
def format(self, record):
log_fmt = self.FORMATS.get(record.levelno)
formatter = logging.Formatter(log_fmt)
return formatter.format(record)
def setup_logger(name):
handler = logging.StreamHandler()
handler.setFormatter(CustomFormatter())
logger = logging.getLogger(name)
logger.setLevel(logging.INFO)
logger.addHandler(handler)
return logger