Files
UniXNU/scripts/derive-a740-pwrup.py

85 lines
4.0 KiB
Python

#!/usr/bin/env python3
"""Derive the A740 preemption register list from pinned sources only."""
import hashlib, json, re, sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
XML = ROOT / '.cache/adreno-source/drivers/gpu/drm/msm/registers/adreno'
CATALOG = ROOT / '.cache/adreno-source/drivers/gpu/drm/msm/adreno/a6xx_catalog.c'
ORDER = ['A2XX', 'A3XX', 'A4XX', 'A5XX', 'A6XX', 'A7XX', 'A8XX']
TARGET = 'A7XX'
def matches(variants):
if variants is None:
return True
if '-' in variants:
left, right = variants.split('-', 1)
low = ORDER.index(left) if left else 0
high = ORDER.index(right) if right else len(ORDER) - 1
return low <= ORDER.index(TARGET) <= high
return variants == TARGET
def main():
check_only = '--check' in sys.argv[1:]
text = CATALOG.read_text()
block = re.search(r'a7xx_pwrup_reglist_regs\[\]\s*=\s*\{(.*?)\};', text, re.S)
if not block:
raise SystemExit('A740 preemption list absent from the pinned catalog')
catalog = []
for entry in block.group(1).split(','):
entry = entry.strip()
if not entry:
continue
found = re.fullmatch(r'REG_(?:A[0-9]XX_)?([A-Z0-9_]+?)(?:\s*\+\s*(\d+))?', entry)
if not found:
raise SystemExit('Unsupported catalog entry: ' + entry)
catalog.append((found.group(1), int(found.group(2) or 0)))
xmls = {(XML / 'a6xx.xml').read_text(): 'a6xx.xml',
(XML / 'adreno_common.xml').read_text(): 'adreno_common.xml'}
resolved = []
for name, plus in catalog:
hits = []
for source, filename in xmls.items():
for m in re.finditer(r'<reg(32|64) offset="(0x[0-9a-fA-F]+)" name="' + name +
r'"([^>]*)>', source):
variant = re.search(r'variants="([^"]+)"', m.group(3))
if matches(variant.group(1) if variant else None):
hits.append((int(m.group(2), 16), m.group(1), filename))
offsets = {h[0] for h in hits}
if len(offsets) != 1:
raise SystemExit('Ambiguous or missing ' + name + ': ' + repr(hits))
resolved.append(offsets.pop() + plus)
if check_only:
current = (ROOT / 'drivers/Adreno740/NativeAdrenoPwrupRegs.h').read_text()
expected = [int(v, 16) for v in re.findall(r'0x([0-9a-fA-F]{8}),', current)]
if expected != resolved:
raise SystemExit('A740 power-up register table is stale: ' + repr((expected, resolved)))
print('PASS: pinned catalogue resolves to the committed %d A740 power-up registers' % len(resolved))
return
header = '''/* SPDX-License-Identifier: MIT */
#ifndef NATIVE_ADRENO_PWRUP_REGS_H
#define NATIVE_ADRENO_PWRUP_REGS_H
#include <stdint.h>
/* Generated by scripts/derive-a740-pwrup.py from the pinned
* a6xx_catalog.c list and the pinned XMLs, selecting only entries whose
* variants include A7XX. Do not edit by hand. */
static const uint32_t NativeAdrenoA740PwrupRegs[]={
''' + ''.join(' 0x%08x,%s\n' % (v, '' if i % 4 != 3 else '') for i, v in enumerate(resolved)) + '''};
#define NATIVE_ADRENO_A740_PWRUP_COUNT \\
(sizeof(NativeAdrenoA740PwrupRegs)/sizeof(NativeAdrenoA740PwrupRegs[0]))
#endif
'''
generated = ROOT / 'build/adreno740/include/NativeAdrenoPwrupRegs.h'
generated.parent.mkdir(parents=True, exist_ok=True)
generated.write_text(header)
report = dict(catalog=[{'name': n, 'plus': p} for n, p in catalog],
resolved=resolved, count=len(resolved),
xml_sha256={f: hashlib.sha256((XML / f).read_bytes()).hexdigest()
for f in ('a6xx.xml', 'adreno_common.xml')},
catalog_sha256=hashlib.sha256(CATALOG.read_bytes()).hexdigest())
out = ROOT / 'build/adreno-pwrup'; out.mkdir(parents=True, exist_ok=True)
(out / 'report.json').write_text(json.dumps(report, indent=2) + '\n')
print('PASS: %d A740 preemption registers resolved with exact A7XX variant selection' % len(resolved))
if __name__ == '__main__':
main()