85 lines
4.0 KiB
Python
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()
|