Files
my-os-project2/kernel/hal/x86_64/uACPI/tests/utilities/asl.py
2025-08-17 18:37:57 +02:00

218 lines
6.0 KiB
Python

import os
import subprocess
from typing import List, Optional, Union
class ASL:
@staticmethod
def definition_block(kind: str, revision: int) -> str:
block = "DefinitionBlock "
block += f'("", "{kind}", {revision}, '
block += '"uTEST", "TESTTABL", 0xF0F0F0F0)'
return block
@staticmethod
def name(name: str, term_arg: Union[str, int]) -> str:
return f"Name({name}, {term_arg})"
@staticmethod
def buffer(
initializers: Optional[List[int]] = None,
count: Optional[int] = None
) -> str:
if count is not None:
buf_len = count
elif initializers is not None:
buf_len = len(initializers)
else:
buf_len = 0
buf = f"Buffer({buf_len})"
buf += " { "
if initializers is not None:
buf += ", ".join([str(x) for x in initializers])
buf += " }"
return buf
@staticmethod
def method(name: str, num_args: Optional[int] = None) -> str:
method = f"Method ({name}"
if num_args is not None:
method += f", {num_args}"
method += ")"
return method
@staticmethod
def invoke(name: str, args: List[str] = []) -> str:
invocation = f"{name}("
invocation += ", ".join(args)
invocation += ")"
return invocation
@staticmethod
def end_block() -> str:
return "}"
@staticmethod
def assign(dst: str, src: str) -> str:
return f"{dst} = {src}"
@staticmethod
def increment(name: str) -> str:
return f"{name}++"
@staticmethod
def create_field(buf: str, idx: int, field_size: int,
field_name: str) -> str:
return f"CreateField({buf}, {idx}, {field_size}, {field_name})"
@staticmethod
def iff(arg: str) -> str:
return f"If ({arg})"
@staticmethod
def elsee() -> str:
return "Else"
@staticmethod
def equal(arg0: str, arg1: str) -> str:
return f"{arg0} == {arg1}"
@staticmethod
def returnn(arg: str) -> str:
return f"Return ({arg})"
class ASLSource:
def __init__(self, revision: int = 0):
self.lines: List[str] = []
self.revision = revision
self.indentation = 0
self.l(ASL.definition_block("DSDT", 2))
self.block_begin()
def l(self, line: str) -> None:
line = " " * (self.indentation * 4) + line
self.lines.append(line)
def block_begin(self) -> None:
self.l("{")
self.indentation += 1
def block_end(self) -> None:
self.indentation -= 1
self.l("}\n")
def iff(self, arg: str) -> None:
self.l(ASL.iff(arg) + " {")
self.indentation += 1
def elsee(self) -> None:
self.indentation -= 1
self.l("} Else {")
self.indentation += 1
def finalize(self) -> None:
self.block_end()
def dump(self, path: str) -> None:
with open(path, "w") as f:
f.write("\n".join(self.lines))
def dump_as_test_case(
self, path: str, case_name: str,
expected_type: str, expected_value: Union[str, int]
) -> None:
with open(path, "w") as f:
f.write(f"// Name: (generated) {case_name}\n")
f.write(f"// Expect: {expected_type} => {expected_value}\n")
f.write("\n".join(self.lines))
@staticmethod
def compile(path: str, compiler: str, bin_dir: str) -> str:
case_aml_name = os.path.basename(path).rsplit(".", 1)[0] + ".aml"
out_case = os.path.join(bin_dir, case_aml_name)
ignored_warnings = [
# Warning 3144 Method Local is set but never used
"-vw", "3144",
# Remark 2098 Recursive method call
"-vw", "2098",
# Invalid type [Reference] found, RefOf operator requires
# [Integer|String|Buffer|Package|FieldUnit|Device|Event|
# Method|Mutex|Region|Power|Processor|Thermal|BufferField|
# DdbHandle|DebugObject]
"-vw", "6058",
# One or more objects within the Pathname do not exist
"-vw", "6161",
# Too few arguments
"-vw", "6005",
# Called method returns no value
"-vw", "6080",
# Object does not exist
"-vw", "6084",
# Not a control method, cannot invoke
"-vw", "6086",
# Object is not referenced
"-vw", "2089",
# Creation of named objects within a method is highly inefficient
"-vw", "2173",
# Existing object has invalid type for Scope operator
"-vw", "6117",
# Switch expression is not a static Integer/Buffer/String data
"-vw", "3124",
# Static OperationRegion should be declared outside control method
"-vw", "3175",
# Missing dependency
# (for some reason it has two different error codes)
"-vw", "3141",
"-vw", "6141",
# Field Unit extends beyond region limit
"-vw", "6031",
# Name already exists in scope
"-vw", "6074",
# Object not found or not accessible from current scope
"-vw", "6085",
# Legacy Processor() keyword detected. Use Device() keyword instead
"-vw", "3168",
# Local or Arg used outside a control method
"-vw", "2067",
]
args = [compiler, *ignored_warnings, "-oa", "-p", out_case, path]
proc = subprocess.Popen(args, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True)
proc.wait(10)
stdout = proc.stdout
assert stdout
stderr = proc.stderr
assert stderr
if proc.returncode != 0:
raise RuntimeError(f"Compiler error:\nstdout:\n{stdout.read()}"
f"\nstderr:\n{stderr.read()}")
return out_case