test(bios): integrate pinned BIOS read-protection baseline
Add --suite bios with hash-verified upstream files and the ARM evaluation checkpoint at 0x08000248. Preserve the r12=0 assertion, original BIOS boot, and all test bytes. Add synthetic adapter and CLI regressions. On Darwin arm64 the public ROM fails test 1 in debug and release after 64 steps and 543 nominal cycles. Document that this tests protected reads of Nintendo firmware opcodes, not general BIOS service compatibility. Online and offline preparation agree; 39 Python tests pass. Core behavior is unchanged.
This commit is contained in:
parent
661f00d682
commit
6e736c634b
11 changed files with 143 additions and 8 deletions
46
tools/gba-tests-bios.lock.json
Normal file
46
tools/gba-tests-bios.lock.json
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"repository": "jsmolka/gba-tests",
|
||||
"revision": "a7113b67e63f83a9b321696ddd7042ccfad6c881",
|
||||
"license": "MIT",
|
||||
"rom": "bios/bios.gba",
|
||||
"completion_pc": "0x08000248",
|
||||
"result_register": 12,
|
||||
"files": {
|
||||
"LICENSE": {
|
||||
"sha256": "b59a9ed235d76752c977f04116bc72155a14af48176bdbf50d7e5c29fca35aa7",
|
||||
"bytes": 1070
|
||||
},
|
||||
"README.md": {
|
||||
"sha256": "488f50d9d9031c88cea4161fad69f6460209dd54d965645fa45cf5e972cc9062",
|
||||
"bytes": 434
|
||||
},
|
||||
"bios/bios.asm": {
|
||||
"sha256": "aebc912f7634aca29d926bef61858d59c370a4d96728e53b4cc63d60641dd118",
|
||||
"bytes": 2211
|
||||
},
|
||||
"bios/bios.gba": {
|
||||
"sha256": "9d7b369fa1aa661ff03692b3d79c6f644b623d72983d0fc890e6d87a0409a3c9",
|
||||
"bytes": 1908
|
||||
},
|
||||
"lib/constants.inc": {
|
||||
"sha256": "b4dd3f4760ac1ae7e99cdc7e255f8220eed666e1ab821b150561db58e5d3b7ea",
|
||||
"bytes": 900
|
||||
},
|
||||
"lib/macros.inc": {
|
||||
"sha256": "25b0ff553c4ca99d76ec82c8c9db874e25d6eed58e2e69fa27f1a0fe7a8c46d4",
|
||||
"bytes": 2864
|
||||
},
|
||||
"lib/header.asm": {
|
||||
"sha256": "e9d1e8c7b6382eeb1b7059423ec365e32911f702eadfa51804a2119438a87357",
|
||||
"bytes": 1720
|
||||
},
|
||||
"lib/text.asm": {
|
||||
"sha256": "77e579d6cf0db182fd24e8d420c8c0a81592d78197e8fb06accc8bcfb43db17e",
|
||||
"bytes": 2288
|
||||
},
|
||||
"lib/glyphs.asm": {
|
||||
"sha256": "538beb37f40b1fd56beed9253e0e9eab25444c748adba7440a2093f49e3cbcc9",
|
||||
"bytes": 2545
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Prepare a pinned public ARM, Thumb, or memory test outside tracked paths.
|
||||
"""Prepare a pinned public ARM, Thumb, memory, or BIOS test outside tracked paths.
|
||||
|
||||
This adapter is original. Upstream sources, license, and ROM bytes are downloaded
|
||||
only to the requested local directory. They are not embedded in this repository.
|
||||
|
|
@ -15,7 +15,7 @@ from urllib.request import Request, urlopen
|
|||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
LOCKS = {suite: Path(__file__).with_name(f"gba-tests-{suite}.lock.json")
|
||||
for suite in ("arm", "thumb", "memory")}
|
||||
for suite in ("arm", "thumb", "memory", "bios")}
|
||||
MAX_FILE_BYTES = 1024 * 1024
|
||||
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ def prepare(output, source=None, download=fetch, suite="arm"):
|
|||
files[name] = data
|
||||
|
||||
# The source-defined eval label starts with m_vsync's register save. All
|
||||
# failure exits set the result register (ARM/memory r12, Thumb r7).
|
||||
# failure exits set the result register (ARM/memory/BIOS r12, Thumb r7).
|
||||
# Thumb tests switch back to ARM before eval. Success leaves the result zero.
|
||||
# Hash pinning is authoritative; these checks catch adapter-offset mistakes.
|
||||
pc = int(lock["completion_pc"], 16)
|
||||
|
|
|
|||
|
|
@ -26,9 +26,12 @@ class PreparationTests(unittest.TestCase):
|
|||
elif self.suite == "thumb":
|
||||
data = struct.pack("<IIHHI", 0xEAFFFFFE, 0xE1A00000, 0xA000, 0x4700, 0xE92D0003)
|
||||
pc, result = "0x0800000c", 7
|
||||
else:
|
||||
elif self.suite == "memory":
|
||||
data = struct.pack("<III", 0xEAFFFFFE, 0xE1A00000, 0xE92D0003)
|
||||
pc, result = "0x08000008", 12
|
||||
else:
|
||||
data = struct.pack("<IIII", 0xEAFFFFFE, 0xE1A00000, 0xE1A00000, 0xE92D0003)
|
||||
pc, result = "0x0800000c", 12
|
||||
self.files = {
|
||||
self.rom: data,
|
||||
"LICENSE": b"Original fixture, not upstream license content.\n",
|
||||
|
|
@ -192,6 +195,10 @@ class MemoryPreparationTests(PreparationTests):
|
|||
suite = "memory"
|
||||
|
||||
|
||||
class BiosPreparationTests(PreparationTests):
|
||||
suite = "bios"
|
||||
|
||||
|
||||
class SuiteSelectionTests(unittest.TestCase):
|
||||
def test_unknown_suite_is_rejected_before_download_or_output(self):
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
|
|
@ -210,6 +217,7 @@ class SuiteSelectionTests(unittest.TestCase):
|
|||
("arm", "0x08001d4c", 12),
|
||||
("thumb", "0x08000934", 7),
|
||||
("memory", "0x08000350", 12),
|
||||
("bios", "0x08000248", 12),
|
||||
]:
|
||||
lock = json.loads(adapter.LOCKS[suite].read_text())
|
||||
self.assertEqual(lock["repository"], "jsmolka/gba-tests")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue