|
2 | 2 | """Build the H7607BA.300 ACPI overrides from this P16's own firmware tables. |
3 | 3 |
|
4 | 4 | No firmware table, nor anything derived from one, is distributed. Dump the |
5 | | -DSDT and SSDTs of your own P16 into a directory and pass it as --dump: |
| 5 | +ASUS SSDT of your own P16 into a directory and pass it as --dump: |
6 | 6 |
|
7 | 7 | UEFI: scripts/stage-acpi-dump.py stages the EDK2 Shell and a dump script on |
8 | 8 | a mounted FAT32 stick. Boot the P16 from it with Secure Boot disabled; the |
|
11 | 11 | Linux booted without h7607a-acpi.cpio, such as another distribution's live |
12 | 12 | system on this P16: |
13 | 13 | mkdir DIR |
14 | | - for table in /sys/firmware/acpi/tables/DSDT /sys/firmware/acpi/tables/SSDT*; do |
| 14 | + for table in /sys/firmware/acpi/tables/SSDT*; do |
15 | 15 | sudo cat "$table" | tee "DIR/${table##*/}" > /dev/null |
16 | 16 | done |
17 | 17 |
|
18 | | -The DSDT and the ASUS SSDT (OEM ID _ASUS_, table ID ASUSSSDT) must be those of |
19 | | -firmware H7607BA.300. power-source.dsl is that SSDT disassembled by ACPICA iasl |
20 | | -20260408 and edited by power-source.sed. SSPM changes only its _STA predicate, |
21 | | -and six compiled ASUS methods are spliced into the original SSDT, since |
22 | | -compiling the whole table would rewrite unrelated AML. The two tables, the ASL |
23 | | -and the archive are written to their collection paths once every pinned hash |
24 | | -matches. |
| 18 | +The ASUS SSDT (OEM ID _ASUS_, table ID ASUSSSDT) must be from firmware |
| 19 | +H7607BA.300. power-source.dsl is that table disassembled by ACPICA iasl |
| 20 | +20260408 and edited by power-source.sed. Six compiled ASUS methods are |
| 21 | +spliced into the original SSDT. The SSDT, ASL and archive are written only |
| 22 | +after every pinned hash matches. |
| 23 | +
|
| 24 | +The native DSDT stays in use. Its firmware-data addresses can change between |
| 25 | +boots even on the same BIOS. The required acpi_osi="!Windows 2022" boot option |
| 26 | +already enables SSPM without replacing that table. |
25 | 27 | """ |
26 | 28 | import argparse |
27 | 29 | import hashlib |
|
37 | 39 |
|
38 | 40 | REPO = Path(__file__).resolve().parents[2] |
39 | 41 | FIRMWARE = "H7607BA.300" |
40 | | -DSDT_INPUT = "0b9ed92671568cf36bade16262d068d1a4f3c85634159de46ae00bf0f727a402" |
41 | 42 | SSDT_INPUT = "46d9ed16af06093cdb849df69646683317d53d7342dfd38f24eab00795d396f0" |
42 | 43 | ASL_INPUT = "cff6e8be5665686c95bd83b5e2d73ed0abbacddecc416e57dbd29f91a746472a" |
43 | | -DSDT_OUTPUT = "80e0ad4a051704003d09029cb600a9814e1cd370ce774b9749dc09d2232b5aaf" |
44 | 44 | SSDT_OUTPUT = "9b28ffc14c19f8b7ea2278de88ff9ec070f5f70401107d81fef067a916aa9695" |
45 | | -ARCHIVE_OUTPUT = "311dc5b456f1b7a9728814cd8ca105370bdca8383facec141f23217f43eac51d" |
| 45 | +ARCHIVE_OUTPUT = "68420c5248a237b01267bf8713867f53358252d0d3935fb09c0e66b02c39153e" |
46 | 46 | METHODS = ("RRA9", "RRA8", "WRA9", "WRA8", "RWEC", "GBST") |
47 | 47 | ASUS_SSDT = b"_ASUS_ASUSSSDT" |
48 | | -DSDT_PATH = "assets/hardware/uefi/n1x-dsdt-baseline.bin" |
49 | 48 | SSDT_PATH = "assets/hardware/uefi/n1x-asus-ssdt-baseline.bin" |
50 | 49 | ASL_PATH = "provenance/hardware/power-source.dsl" |
51 | 50 | ARCHIVE_PATH = "assets/hardware/acpi/h7607a-acpi.cpio" |
@@ -97,21 +96,6 @@ def encode_length(length, width): |
97 | 96 | [(length >> (4 + i * 8)) & 255 for i in range(width - 1)]) |
98 | 97 |
|
99 | 98 |
|
100 | | -def patch_dsdt(original): |
101 | | - exact(original, DSDT_INPUT, "Firmware DSDT") |
102 | | - table(original, b"DSDT", b"NVDA\0\0ANGUS ", 4) |
103 | | - start = 0x10269 |
104 | | - predicate = b"_OSI\x0dWindows 2022\0" |
105 | | - require(original[start:start + len(predicate)] == predicate, "SSPM predicate changed") |
106 | | - modified = bytearray(original) |
107 | | - modified[start:start + len(predicate)] = b"\0" + b"\xa3" * (len(predicate) - 1) |
108 | | - struct.pack_into("<I", modified, 24, 5) |
109 | | - modified[9] = 0 |
110 | | - modified[9] = -sum(modified) % 256 |
111 | | - table(modified, b"DSDT", b"NVDA\0\0ANGUS ", 5) |
112 | | - return exact(bytes(modified), DSDT_OUTPUT, "SSPM override") |
113 | | - |
114 | | - |
115 | 99 | def compiled_method(compiled, name, digest): |
116 | 100 | matches = [] |
117 | 101 | for offset in range(36, len(compiled) - 6): |
@@ -173,23 +157,21 @@ def member(name, data, mode, inode): |
173 | 157 | return entry + bytes(-len(entry) % 4) |
174 | 158 |
|
175 | 159 |
|
176 | | -def archive(dsdt, ssdt): |
177 | | - exact(dsdt, DSDT_OUTPUT, "SSPM override") |
| 160 | +def archive(ssdt): |
178 | 161 | exact(ssdt, SSDT_OUTPUT, "ASUS power override") |
179 | 162 | result = b"".join(member(name, b"", stat.S_IFDIR | 0o755, inode) |
180 | 163 | for inode, name in enumerate(("kernel", "kernel/firmware", "kernel/firmware/acpi"), 1)) |
181 | | - result += member("kernel/firmware/acpi/DSDT.aml", dsdt, stat.S_IFREG | 0o644, 4) |
182 | | - result += member("kernel/firmware/acpi/SSDT.aml", ssdt, stat.S_IFREG | 0o644, 5) |
183 | | - result += member("TRAILER!!!", b"", 0, 6) |
| 164 | + result += member("kernel/firmware/acpi/SSDT.aml", ssdt, stat.S_IFREG | 0o644, 4) |
| 165 | + result += member("TRAILER!!!", b"", 0, 5) |
184 | 166 | result += bytes(-len(result) % 512) |
185 | 167 | return exact(result, ARCHIVE_OUTPUT, "Production ACPI archive") |
186 | 168 |
|
187 | 169 |
|
188 | 170 | def dumped_tables(dump): |
189 | | - """Map b"DSDT" and b"SSDT" to {table: [file names]} for the DSDT and ASUS SSDT dumps in dump.""" |
| 171 | + """Map ASUS SSDT bytes to their dump file names.""" |
190 | 172 | dump = Path(dump) |
191 | 173 | require(dump.is_dir(), f"{dump} is not a directory") |
192 | | - found = {b"DSDT": {}, b"SSDT": {}} |
| 174 | + found = {b"SSDT": {}} |
193 | 175 | for path in sorted(dump.iterdir()): |
194 | 176 | if not path.is_file(): |
195 | 177 | continue |
@@ -309,47 +291,36 @@ def pins(files): |
309 | 291 | return {name: {"bytes": len(data), "sha256": sha(data)} for name, data in files.items()} |
310 | 292 |
|
311 | 293 |
|
312 | | -def build(dump, *, repo=REPO, iasl="iasl", sspm_only=False): |
| 294 | +def build(dump, *, repo=REPO, iasl="iasl"): |
313 | 295 | repo = Path(repo).resolve() |
314 | 296 | found = dumped_tables(dump) |
315 | | - dsdt_name, dsdt = dumped(found, b"DSDT", "DSDT", dump) |
316 | | - firmware(dsdt_name, dsdt, DSDT_INPUT, DSDT_OUTPUT, "DSDT") |
317 | | - overrides = {"DSDT.aml": patch_dsdt(dsdt)} |
318 | | - files = {DSDT_PATH: dsdt} |
319 | | - names = {"DSDT": dsdt_name} |
320 | | - compiler = None |
321 | | - if not sspm_only: |
322 | | - ssdt_name, ssdt = dumped(found, b"SSDT", "ASUS SSDT (OEM ID _ASUS_, table ID ASUSSSDT)", dump) |
323 | | - firmware(ssdt_name, ssdt, SSDT_INPUT, SSDT_OUTPUT, "ASUS SSDT") |
324 | | - names["SSDT"] = ssdt_name |
325 | | - source = repo / "provenance/hardware" |
326 | | - methods = json.loads((source / "power-method-changes.json").read_text()) |
327 | | - require(tuple(row["method"] for row in methods) == METHODS, "Unexpected ASL method changes") |
328 | | - with tempfile.TemporaryDirectory(prefix="h7607a-acpi-") as work: |
329 | | - work = Path(work) |
330 | | - iasl = check_iasl(iasl, work) |
331 | | - asl = derive_asl(ssdt, (source / "power-source.sed").read_text(), iasl, work) |
332 | | - (work / "power.dsl").write_bytes(asl) |
333 | | - run_iasl(iasl, ["-p", "power", "power.dsl"], work) |
334 | | - compiled = (work / "power.aml").read_bytes() |
335 | | - compiler = "ACPICA iasl 20260408" |
336 | | - overrides["SSDT.aml"] = splice_ssdt(ssdt, compiled, json.loads((source / "power-splice.json").read_text())) |
337 | | - files.update({SSDT_PATH: ssdt, ASL_PATH: asl, |
338 | | - ARCHIVE_PATH: archive(overrides["DSDT.aml"], overrides["SSDT.aml"])}) |
| 297 | + ssdt_name, ssdt = dumped(found, b"SSDT", "ASUS SSDT (OEM ID _ASUS_, table ID ASUSSSDT)", dump) |
| 298 | + firmware(ssdt_name, ssdt, SSDT_INPUT, SSDT_OUTPUT, "ASUS SSDT") |
| 299 | + source = repo / "provenance/hardware" |
| 300 | + methods = json.loads((source / "power-method-changes.json").read_text()) |
| 301 | + require(tuple(row["method"] for row in methods) == METHODS, "Unexpected ASL method changes") |
| 302 | + with tempfile.TemporaryDirectory(prefix="h7607a-acpi-") as work: |
| 303 | + work = Path(work) |
| 304 | + iasl = check_iasl(iasl, work) |
| 305 | + asl = derive_asl(ssdt, (source / "power-source.sed").read_text(), iasl, work) |
| 306 | + (work / "power.dsl").write_bytes(asl) |
| 307 | + run_iasl(iasl, ["-p", "power", "power.dsl"], work) |
| 308 | + compiled = (work / "power.aml").read_bytes() |
| 309 | + overrides = {"SSDT.aml": splice_ssdt(ssdt, compiled, json.loads((source / "power-splice.json").read_text()))} |
| 310 | + files = {SSDT_PATH: ssdt, ASL_PATH: asl, ARCHIVE_PATH: archive(overrides["SSDT.aml"])} |
339 | 311 | written = publish(repo, files) |
340 | | - return {"schema": 2, "firmware": FIRMWARE, "compiler": compiler, "dump": names, |
| 312 | + return {"schema": 2, "firmware": FIRMWARE, "compiler": "ACPICA iasl 20260408", "dump": {"SSDT": ssdt_name}, |
341 | 313 | "overrides": pins(overrides), "outputs": pins(files), "written": written} |
342 | 314 |
|
343 | 315 |
|
344 | | -def cli(*, sspm_only=False): |
| 316 | +def cli(): |
345 | 317 | parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) |
346 | 318 | parser.add_argument("--dump", required=True, type=Path, metavar="DIR", |
347 | | - help="Directory holding this P16's DSDT and SSDT dumps") |
348 | | - if not sspm_only: |
349 | | - parser.add_argument("--iasl", default="iasl", help="ACPICA iasl 20260408 executable") |
| 319 | + help="Directory holding this P16's original ASUS SSDT dump") |
| 320 | + parser.add_argument("--iasl", default="iasl", help="ACPICA iasl 20260408 executable") |
350 | 321 | args = parser.parse_args() |
351 | 322 | try: |
352 | | - result = build(args.dump, iasl=getattr(args, "iasl", "iasl"), sspm_only=sspm_only) |
| 323 | + result = build(args.dump, iasl=args.iasl) |
353 | 324 | except (ValueError, OSError, subprocess.SubprocessError) as error: |
354 | 325 | parser.exit(1, f"ACPI build failed: {error}\n") |
355 | 326 | print(json.dumps(result, indent=2)) |
0 commit comments