blob: 23a3b5e00efc772707220146eac2d5a40c9c42db [file] [log] [blame]
#!/usr/bin/env fbpython
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.
import argparse
import csv
import io
import os
import shutil
import subprocess
import tempfile
from pathlib import Path
XTENSA_ROOT = os.environ["XTENSA_TOOLCHAIN"]
XTENSA_VER = os.environ["TOOLCHAIN_VER"]
XTENSA_TOOLS = os.path.join(XTENSA_ROOT, f"{XTENSA_VER}/XtensaTools")
XTENSA_SYSTEM = os.path.join(XTENSA_TOOLS, "config")
XTENSA_CORE = os.environ["XTENSA_CORE"]
def parse_sections(dsp_dir, dsp_exe):
"""
>>> xt-size dsp_mu_polling_hifi4 --radix=16 -A
dsp_mu_polling_hifi4 :
section size addr
.UserExceptionVector.literal 0x4 0x24000000
.ResetVector.text 0x14c 0x24020000
.WindowVectors.text 0x16c 0x24020400
.Level2InterruptVector.text 0x8 0x2402057c
.Level3InterruptVector.text 0x8 0x2402059c
.DebugExceptionVector.text 0xc 0x240205bc
.NMIExceptionVector.text 0x4 0x240205dc
.KernelExceptionVector.text 0x8 0x240205fc
.UserExceptionVector.text 0xc 0x2402061c
.DoubleExceptionVector.text 0x8 0x2402063c
.rodata 0x398 0x200000
.text 0x4c6c 0x2003a0
.clib.data 0x4 0x20500c
.rtos.percpu.data 0x310 0x205010
.data 0x880 0x205320
.bss 0x6b8 0x205ba0
.debug_aranges 0x2c8 0x0
.debug_info 0x4367 0x0
.debug_abbrev 0xf54 0x0
.debug_line 0x36e9 0x0
.debug_frame 0x1f4 0x0
.debug_str 0x1986 0x0
.debug_loc 0x15ba 0x0
.xt.prop 0x4a10 0x0
.xt.lit 0x110 0x0
.xtensa.info 0x218 0x0
.comment 0x5f 0x0
.debug_ranges 0x100 0x0
Total 0x1717f
"""
cmd = f"{XTENSA_TOOLS}/bin/xt-size {dsp_dir}/{dsp_exe} --radix=16 -A"
print(f"Executing command:\n {cmd}\n")
p = subprocess.run(cmd.split(" "), capture_output=True)
print(p.stdout.decode())
lines = p.stdout.decode().strip().split("\n")
print(lines)
lines = [line for line in lines if line != ""]
lines = lines[2:-1]
lines = "\n".join(lines)
f = io.StringIO(lines)
reader = csv.reader(f, delimiter=" ", skipinitialspace=True)
ret_list = [(section, int(addr, 16)) for section, size, addr in reader]
print(lines)
print(ret_list)
return ret_list
def xt_objcopy_sections(dsp_dir, dsp_exe, output_obj_path, obj_name, sections):
xt_objcopy = f"{XTENSA_TOOLS}/bin/xt-objcopy"
xtensa_args = f"--xtensa-system={XTENSA_SYSTEM} --xtensa-core={XTENSA_CORE}"
cmd = f"{xt_objcopy} {xtensa_args} -O binary {dsp_dir}/{dsp_exe} {output_obj_path}/{obj_name} "
cmd += " ".join([f"--only-section={section}" for section in sections])
print(cmd)
subprocess.run(cmd.split(" "), check=True)
def main():
parser = argparse.ArgumentParser()
parser.add_argument("dsp_exe_path", help="Xtensa DSP executable path")
parser.add_argument("output_dir", help="output directory")
args = parser.parse_args()
dsp_exe_dir = os.path.dirname(args.dsp_exe_path)
dsp_exe = os.path.basename(args.dsp_exe_path)
Path(args.output_dir).mkdir(parents=True, exist_ok=True)
sections = parse_sections(dsp_exe_dir, dsp_exe)
DATA_SECTION_START = 0x200000
NCACHE_SECTION_START = 0x20060000
TEXT_SECTION_START = 0x24000000
ncache_sections = [
section
for section, addr in sections
if addr >= NCACHE_SECTION_START and addr < TEXT_SECTION_START
]
data_sections = [
section
for section, addr in sections
if addr < NCACHE_SECTION_START and addr >= DATA_SECTION_START
]
text_sections = [
section for section, addr in sections if addr >= TEXT_SECTION_START
]
if len(ncache_sections):
dirpath = tempfile.mkdtemp()
xt_objcopy_sections(
dsp_exe_dir,
dsp_exe,
dirpath,
"dsp_ncache_release.bin",
ncache_sections,
)
# copy files over
shutil.copyfile(
os.path.join(dirpath, "dsp_ncache_release.bin"),
os.path.join(args.output_dir, "dsp_ncache_release.bin"),
)
shutil.rmtree(dirpath)
dirpath = tempfile.mkdtemp()
xt_objcopy_sections(
dsp_exe_dir,
dsp_exe,
dirpath,
"dsp_text_release.bin",
text_sections,
)
# copy files over
shutil.copyfile(
os.path.join(dirpath, "dsp_text_release.bin"),
os.path.join(args.output_dir, "dsp_text_release.bin"),
)
shutil.rmtree(dirpath)
dirpath = tempfile.mkdtemp()
xt_objcopy_sections(
dsp_exe_dir,
dsp_exe,
dirpath,
"dsp_data_release.bin",
data_sections,
)
# copy files over
shutil.copyfile(
os.path.join(dirpath, "dsp_data_release.bin"),
os.path.join(args.output_dir, "dsp_data_release.bin"),
)
shutil.rmtree(dirpath)
if __name__ == "__main__":
main()