Integrate uACPI

This commit is contained in:
2025-08-17 18:37:57 +02:00
parent 069870cd0d
commit 92ccd189e7
166 changed files with 42104 additions and 33 deletions

View File

@ -0,0 +1,255 @@
import os
import copy
import subprocess
from typing import List, Optional, Callable
from utilities.asl import ASL, ASLSource
ACPICA_BUFFER_PRINT_PREFIX = " 0000: "
def _parse_acpiexec_buffers(raw_output: str) -> List[List[int]]:
lines = raw_output.split("\n")
answers = []
for i, line in enumerate(lines):
if "Evaluating" in line:
lines = lines[i + 1:]
break
for line in lines:
if not line.startswith(ACPICA_BUFFER_PRINT_PREFIX):
continue
line = line.removeprefix(ACPICA_BUFFER_PRINT_PREFIX)
buffer_bytes = []
for x in line.split(" "):
# Buffers are printed out with ascii disassembly at the end.
# Skip as soon as we encounter empty space.
if x == "":
break
buffer_bytes.append(int(x, base=16))
answers.append(buffer_bytes)
return answers
def _generate_for_each_bit_combination(
src: ASLSource, per_combo_cb: Callable,
final_cb: Optional[Callable] = None
) -> None:
methods = []
for i in range(0, 64):
method_name = f"FT{i}"
methods.append(method_name)
src.l(ASL.method(method_name))
src.block_begin()
for j in range(0, 65):
if (i >= j):
continue
per_combo_cb(i, j, src)
src.block_end()
src.l(ASL.method("MAIN"))
src.block_begin()
for method in methods:
src.l(ASL.invoke(method))
if final_cb is not None:
final_cb(src)
src.block_end()
src.finalize()
_READS_ANSWERS_NAME = "buffer-reads-answers"
_WRITES_ANSWERS_NAME = "buffer-writes-answers"
def _generate_buffer_reads_answers(
compiler: str, bin_dir: str, src: ASLSource
) -> List[List[int]]:
output_path = os.path.join(bin_dir, _READS_ANSWERS_NAME + ".aml")
if not os.path.exists(output_path):
_do_generate_buffer_reads_answers(compiler, bin_dir, src)
raw_answers = subprocess.check_output(
["acpiexec", "-b", "execute MAIN", output_path],
universal_newlines=True
)
return _parse_acpiexec_buffers(raw_answers)
def _generate_buffer_writes_answers(
compiler: str, bin_dir: str, src: ASLSource
) -> List[List[int]]:
output_path = os.path.join(bin_dir, _WRITES_ANSWERS_NAME + ".aml")
if not os.path.exists(output_path):
_do_generate_buffer_writes_answers(compiler, bin_dir, src)
raw_answers = subprocess.check_output(
["acpiexec", "-b", "execute MAIN", output_path],
universal_newlines=True
)
return _parse_acpiexec_buffers(raw_answers)
def _do_generate_buffer_reads_answers(
compiler: str, bin_dir: str, src: ASLSource
) -> None:
def gen_buffer_dump(i, j, src):
field_size = j - i
field_name = f"FI{field_size:02X}"
src.l(ASL.create_field("BUFF", i, field_size, field_name))
src.l(ASL.assign("Debug", field_name))
_generate_for_each_bit_combination(src, gen_buffer_dump)
answers_src_path = os.path.join(bin_dir, _READS_ANSWERS_NAME + ".asl")
src.dump(answers_src_path)
ASLSource.compile(answers_src_path, compiler, bin_dir)
def _do_generate_buffer_writes_answers(
compiler: str, bin_dir: str, src: ASLSource
) -> None:
def gen_buffer_dump(i, j, src):
field_size = j - i
field_name = f"FI{field_size:02X}"
src.l(ASL.create_field("BUFX", i, field_size, field_name))
src.l(ASL.assign(field_name, "BUFF"))
src.l(ASL.assign("Debug", field_name))
_generate_for_each_bit_combination(src, gen_buffer_dump)
writes_src_path = os.path.join(bin_dir, _WRITES_ANSWERS_NAME + ".asl")
src.dump(writes_src_path)
ASLSource.compile(writes_src_path, compiler, bin_dir)
_READS_TEST_NAME = "2080-buffer-reads"
_WRITES_TEST_NAME = "2080-buffer-writes"
def generate_buffer_reads_test(compiler: str, bin_dir: str) -> str:
output_path = os.path.join(bin_dir, _READS_TEST_NAME + ".asl")
if os.path.exists(output_path):
return output_path
return _do_generate_buffer_reads_test(compiler, bin_dir)
def generate_buffer_writes_test(compiler: str, bin_dir: str) -> str:
output_path = os.path.join(bin_dir, _WRITES_TEST_NAME + ".asl")
if os.path.exists(output_path):
return output_path
return _do_generate_buffer_writes_test(compiler, bin_dir)
def _generate_buffer_test_prologue() -> ASLSource:
src = ASLSource(2)
src.l(ASL.name(
"BUFF",
ASL.buffer([0xAC, 0x12, 0x42, 0xCA, 0xDE, 0xFF, 0xCB, 0xDD])
))
src.l(ASL.name(
"BUFX",
ASL.buffer(count=8)
))
return src
def _generate_buffer_test_harness(src: ASLSource) -> None:
src.l(ASL.name("FAIL", 0))
src.l(ASL.name("PASS", 0))
src.l(ASL.method("FDBG", 3))
src.block_begin()
src.l(ASL.assign("Debug", "Arg0"))
src.l(ASL.assign("Debug", "Arg1"))
src.l(ASL.assign("Debug", "Arg2"))
src.l(ASL.increment("FAIL"))
src.block_end()
def _do_generate_buffer_reads_test(compiler: str, bin_dir: str) -> str:
src = _generate_buffer_test_prologue()
answers = _generate_buffer_reads_answers(compiler, bin_dir,
copy.deepcopy(src))
_generate_buffer_test_harness(src)
answer_idx = 0
def gen_buffer_check(i, j, src):
nonlocal answer_idx
field_size = j - i
field_name = f"FI{field_size:02X}"
src.l(ASL.create_field("BUFF", i, field_size, field_name))
src.iff(ASL.equal(field_name, ASL.buffer(answers[answer_idx])))
answer_idx += 1
src.l(ASL.increment("PASS"))
src.elsee()
src.l(ASL.invoke("FDBG", [
field_name, "__LINE__", f'"{field_name}"'
]))
src.block_end()
_generate_for_each_bit_combination(src, gen_buffer_check,
lambda src: src.l(ASL.returnn("FAIL")))
test_src_path = os.path.join(bin_dir, _READS_TEST_NAME + ".asl")
src.dump_as_test_case(test_src_path, "Reads from buffer fields",
"int", "0")
return test_src_path
def _do_generate_buffer_writes_test(compiler: str, bin_dir: str) -> str:
src = _generate_buffer_test_prologue()
answers = _generate_buffer_writes_answers(compiler, bin_dir,
copy.deepcopy(src))
_generate_buffer_test_harness(src)
answer_idx = 0
def gen_buffer_check(i, j, src):
nonlocal answer_idx
field_size = j - i
field_name = f"FI{field_size:02X}"
src.l(ASL.create_field("BUFX", i, field_size, field_name))
src.l(ASL.assign(field_name, "BUFF"))
src.iff(ASL.equal(field_name, ASL.buffer(answers[answer_idx])))
answer_idx += 1
src.l(ASL.increment("PASS"))
src.elsee()
src.l(ASL.invoke("FDBG", [
field_name, "__LINE__", f'"{field_name}"'
]))
src.block_end()
src.l(ASL.assign("BUFX", 0))
_generate_for_each_bit_combination(src, gen_buffer_check,
lambda src: src.l(ASL.returnn("FAIL")))
test_src_path = os.path.join(bin_dir, _WRITES_TEST_NAME + ".asl")
src.dump_as_test_case(test_src_path, "Writes to buffer fields",
"int", "0")
return test_src_path