mirror of https://github.com/Nonannet/copapy.git
helper scripts added for running tricore code in qemu. Not working yet.
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
parent
6a08c59a33
commit
49d8d95773
|
|
@ -36,7 +36,7 @@ echo - Compile stencil test...
|
||||||
cl /Zi /Od stencils\test.c /Fe:build\stencils\test.exe
|
cl /Zi /Od stencils\test.c /Fe:build\stencils\test.exe
|
||||||
|
|
||||||
echo - Build runner for Windows 64 bit...
|
echo - Build runner for Windows 64 bit...
|
||||||
cl /Zi /Od /DENABLE_BASIC_LOGGING ^
|
cl /Zi /Od /DENABLE_LOGGING ^
|
||||||
src\coparun\runmem.c ^
|
src\coparun\runmem.c ^
|
||||||
src\coparun\coparun.c ^
|
src\coparun\coparun.c ^
|
||||||
src\coparun\mem_man.c ^
|
src\coparun\mem_man.c ^
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
from copapy import value
|
||||||
|
from copapy.backend import Store, compile_to_dag, stencil_db_from_package
|
||||||
|
from copapy._binwrite import Command
|
||||||
|
|
||||||
|
input = value(9.0)
|
||||||
|
|
||||||
|
result = input ** 2 / 3.3 + 5
|
||||||
|
|
||||||
|
sdb = stencil_db_from_package('tricore')
|
||||||
|
dw, _ = compile_to_dag([Store(result)], sdb)
|
||||||
|
|
||||||
|
# Instruct runner to dump patched code to a file:
|
||||||
|
dw.write_com(Command.DUMP_CODE)
|
||||||
|
|
||||||
|
dw.to_file('build/runner/test-tricore.copapy')
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Load two raw blobs into qemu-system-tricore memory and execute them
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import shutil
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
if os.name == 'nt':
|
||||||
|
QEMU_BIN = ['wsl', '/opt/tricore/bin/qemu-system-tricore']
|
||||||
|
else:
|
||||||
|
QEMU_BIN = ['qemu-system-tricore']
|
||||||
|
|
||||||
|
MACHINE = "tc27x"
|
||||||
|
RESET_VECTOR = 0x80000000
|
||||||
|
|
||||||
|
def check_qemu():
|
||||||
|
if os.name == 'nt':
|
||||||
|
# On Windows, just check if wsl is available
|
||||||
|
if shutil.which('wsl') is None:
|
||||||
|
print("Cannot find 'wsl' in PATH")
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
if shutil.which(QEMU_BIN[0]) is None:
|
||||||
|
print(f"Cannot find {QEMU_BIN[0]} in PATH")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def make_jump_trampoline(entry_addr: int, out_file: Path):
|
||||||
|
"""
|
||||||
|
Generate a TriCore jump instruction to entry_addr from RESET_VECTOR.
|
||||||
|
Uses a 24-bit relative jump instruction: j offset
|
||||||
|
|
||||||
|
Instruction encoding:
|
||||||
|
- Byte 0: 0x1d (opcode for relative jump)
|
||||||
|
- Bytes 1-3: 24-bit signed relative offset
|
||||||
|
|
||||||
|
Raises an error if the offset doesn't fit in 24 bits.
|
||||||
|
"""
|
||||||
|
# Calculate relative offset from RESET_VECTOR to entry_addr
|
||||||
|
# offset = entry_addr - (RESET_VECTOR + instruction_size)
|
||||||
|
offset = entry_addr - (RESET_VECTOR + 4)
|
||||||
|
|
||||||
|
# Check if offset fits in 24-bit signed range: [-2^23, 2^23-1]
|
||||||
|
max_24bit = (1 << 23) - 1
|
||||||
|
min_24bit = -(1 << 23)
|
||||||
|
|
||||||
|
if offset < min_24bit or offset > max_24bit:
|
||||||
|
raise ValueError(
|
||||||
|
f"24-bit relative jump is not sufficient. "
|
||||||
|
f"Offset {offset} (0x{offset:x}) is outside [-2^23, 2^23-1] range. "
|
||||||
|
f"RESET_VECTOR: 0x{RESET_VECTOR:x}, entry_addr: 0x{entry_addr:x}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Encode the 24-bit offset in little-endian format (3 bytes)
|
||||||
|
offset_bytes = offset.to_bytes(3, byteorder='little', signed=True)
|
||||||
|
|
||||||
|
# Create the jump instruction: opcode (0x1d) + 24-bit offset
|
||||||
|
instruction = bytes([0x1d]) + offset_bytes
|
||||||
|
|
||||||
|
out_file.write_bytes(instruction)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
ap = argparse.ArgumentParser()
|
||||||
|
ap.add_argument("--code", required=True, help="code blob")
|
||||||
|
ap.add_argument("--data", required=True, help="data blob")
|
||||||
|
ap.add_argument("--code-addr", required=True, type=lambda x:int(x,0))
|
||||||
|
ap.add_argument("--data-addr", required=True, type=lambda x:int(x,0))
|
||||||
|
ap.add_argument("--entry", required=True, type=lambda x:int(x,0))
|
||||||
|
ap.add_argument("--machine", default=MACHINE)
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
check_qemu()
|
||||||
|
|
||||||
|
# Create temporary file for trampoline
|
||||||
|
with tempfile.NamedTemporaryFile(delete=False, suffix='.bin') as tmp:
|
||||||
|
tramp = Path(tmp.name)
|
||||||
|
|
||||||
|
try:
|
||||||
|
make_jump_trampoline(args.entry, tramp)
|
||||||
|
|
||||||
|
cmd = list(QEMU_BIN) + [
|
||||||
|
"-M", args.machine,
|
||||||
|
"-nographic",
|
||||||
|
|
||||||
|
# reset vector trampoline
|
||||||
|
"-device", f"loader,file={tramp},addr=0x{RESET_VECTOR:x}",
|
||||||
|
|
||||||
|
# user code/data
|
||||||
|
"-device", f"loader,file={args.code},addr=0x{args.code_addr:x}",
|
||||||
|
"-device", f"loader,file={args.data},addr=0x{args.data_addr:x}",
|
||||||
|
|
||||||
|
# logs
|
||||||
|
"-d", "in_asm,exec,cpu,guest_errors",
|
||||||
|
"-D", "qemu.log",
|
||||||
|
]
|
||||||
|
|
||||||
|
print("Running:")
|
||||||
|
print(" ".join(cmd))
|
||||||
|
print()
|
||||||
|
|
||||||
|
subprocess.run(cmd)
|
||||||
|
finally:
|
||||||
|
# Clean up temporary file
|
||||||
|
if tramp.exists():
|
||||||
|
tramp.unlink()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
python tools\tricore\make_trc_example.py
|
||||||
|
build\runner\coparun build/runner/test-tricore.copapy build/runner/test-tricore.copapy.bin
|
||||||
|
python .\tools\tricore\run_qemu.py --code build/runner/test-tricore.copapy.bin
|
||||||
Loading…
Reference in New Issue