-
Notifications
You must be signed in to change notification settings - Fork 351
Native sim support #10621
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Native sim support #10621
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| CONFIG_ZEPHYR_POSIX=y | ||
| CONFIG_SYS_HEAP_BIG_ONLY=y | ||
| CONFIG_ZEPHYR_NATIVE_DRIVERS=y | ||
| CONFIG_ZEPHYR_LOG=y |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -76,9 +76,12 @@ def main(): | |
| parser = argparse.ArgumentParser(description="Run QEMU via west and automatically decode crashes.") | ||
| parser.add_argument("--build-dir", default="build", help="Path to the build directory containing zephyr.elf, linker.cmd, etc. Defaults to 'build'.") | ||
| parser.add_argument("--log-file", default="qemu-run.log", help="Path to save the QEMU output log. Defaults to 'qemu-run.log'.") | ||
| parser.add_argument("--valgrind", action="store_true", help="Run the executable under Valgrind (only valid for native_sim).") | ||
| args = parser.parse_args() | ||
|
|
||
| # Make absolute path just in case | ||
| # The shell script cd's into `args.build_dir` before executing us, so `args.build_dir` might be relative to the shell script's pwd. | ||
| # We resolve it relative to the python script's original invocation cwd. | ||
| build_dir = os.path.abspath(args.build_dir) | ||
|
|
||
| print(f"Starting QEMU test runner. Monitoring for crashes (Build Dir: {args.build_dir})...") | ||
|
|
@@ -91,7 +94,53 @@ def main(): | |
| print("Please ensure you have sourced the Zephyr environment (e.g., source zephyr-env.sh).") | ||
| sys.exit(1) | ||
|
|
||
| child = pexpect.spawn(west_path, ["-v", "build", "-t", "run"], encoding='utf-8') | ||
| # Detect the board configuration from CMakeCache.txt | ||
| is_native_sim = False | ||
|
|
||
| cmake_cache = os.path.join(build_dir, "CMakeCache.txt") | ||
|
|
||
| if os.path.isfile(cmake_cache): | ||
| with open(cmake_cache, "r") as f: | ||
| for line in f: | ||
| if line.startswith("CACHED_BOARD:STRING=") or line.startswith("BOARD:STRING="): | ||
| if "native_sim" in line.split("=", 1)[1].strip(): | ||
| is_native_sim = True | ||
| break | ||
|
|
||
| # Determine execution command | ||
| # If the user is running the python script directly from outside the workspace, we need to provide the source directory. | ||
| # But if west finds it automatically (or we are in the build dir), providing `-s` might clear the CACHED_BOARD config. | ||
| run_cmd = [west_path, "-v", "build", "-d", build_dir] | ||
|
|
||
| # Check if we are physically sitting inside the build directory | ||
| if os.path.abspath(".") != os.path.abspath(build_dir): | ||
| # We need to explicitly supply the app source to prevent west from crashing | ||
| app_source_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "app")) | ||
| run_cmd.extend(["-s", app_source_dir]) | ||
|
|
||
| run_cmd.extend(["-t", "run"]) | ||
|
|
||
| if args.valgrind: | ||
| if not is_native_sim: | ||
| print("[sof-qemu-run] Error: --valgrind is only supported for the native_sim board.") | ||
| sys.exit(1) | ||
|
|
||
| print("[sof-qemu-run] Rebuilding before valgrind...") | ||
| subprocess.run([west_path, "build", "-d", build_dir], check=True) | ||
|
|
||
| valgrind_path = shutil.which("valgrind") | ||
| if not valgrind_path: | ||
| print("[sof-qemu-run] Error: 'valgrind' command not found in PATH.") | ||
| sys.exit(1) | ||
|
|
||
| exe_path = os.path.join(build_dir, "zephyr", "zephyr.exe") | ||
| if not os.path.isfile(exe_path): | ||
| print(f"[sof-qemu-run] Error: Executable not found at {exe_path}") | ||
| sys.exit(1) | ||
|
|
||
| run_cmd = [valgrind_path, exe_path] | ||
|
|
||
| child = pexpect.spawn(run_cmd[0], run_cmd[1:], encoding='utf-8') | ||
|
|
||
| # We will accumulate output to check for crashes | ||
| full_output = "" | ||
|
|
@@ -157,11 +206,14 @@ def main(): | |
|
|
||
| run_sof_crash_decode(build_dir, full_output) | ||
| else: | ||
| print("\n[sof-qemu-run] No crash detected. Interacting with QEMU Monitor to grab registers...") | ||
| if is_native_sim: | ||
| print("\n[sof-qemu-run] No crash detected. (Skipping QEMU monitor interaction for native_sim)") | ||
| else: | ||
| print("\n[sof-qemu-run] No crash detected. Interacting with QEMU Monitor to grab registers...") | ||
|
|
||
| # We need to send Ctrl-A c to enter the monitor | ||
| if child.isalive(): | ||
| child.send("\x01c") # Ctrl-A c | ||
| # We need to send Ctrl-A c to enter the monitor | ||
| if child.isalive(): | ||
| child.send("\x01c") # Ctrl-A c | ||
| try: | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldn't this |
||
| # Wait for (qemu) prompt | ||
| child.expect(r"\(qemu\)", timeout=5) | ||
|
|
@@ -185,8 +237,8 @@ def main(): | |
| child.close(force=True) | ||
| except pexpect.EOF: | ||
| print("\n[sof-qemu-run] QEMU terminated before we could run monitor commands.") | ||
| else: | ||
| print("\n[sof-qemu-run] Process is no longer alive, cannot extract registers.") | ||
| else: | ||
| print("\n[sof-qemu-run] Process is no longer alive, cannot extract registers.") | ||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -2,8 +2,21 @@ | |||||
| # SPDX-License-Identifier: BSD-3-Clause | ||||||
| # Copyright(c) 2026 Intel Corporation. All rights reserved. | ||||||
|
|
||||||
| # Define the build directory from the first argument (or default) | ||||||
| BUILD_DIR="${1:-build}" | ||||||
| BUILD_DIR="../build-native_sim" | ||||||
| VALGRIND_ARG="" | ||||||
|
Comment on lines
+5
to
+6
|
||||||
|
|
||||||
| while [[ $# -gt 0 ]]; do | ||||||
| case $1 in | ||||||
| --valgrind) | ||||||
| VALGRIND_ARG="--valgrind" | ||||||
| shift | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could just have a single |
||||||
| ;; | ||||||
| *) | ||||||
| BUILD_DIR="$1" | ||||||
| shift | ||||||
| ;; | ||||||
| esac | ||||||
| done | ||||||
|
|
||||||
| # Find and source the zephyr environment script, typically via the sof-venv wrapper | ||||||
| # or directly if running in a known zephyrproject layout. | ||||||
|
|
@@ -24,5 +37,5 @@ source ${VENV_DIR}/bin/activate | |||||
| cd "${BUILD_DIR}" || exit 1 | ||||||
|
|
||||||
| # Finally run the python script which will now correctly inherit 'west' from the sourced environment. | ||||||
| python3 "${SCRIPT_DIR}/sof-qemu-run.py" --build-dir "${BUILD_DIR}" | ||||||
| python3 "${SCRIPT_DIR}/sof-qemu-run.py" --build-dir "${BUILD_DIR}" $VALGRIND_ARG | ||||||
|
||||||
| python3 "${SCRIPT_DIR}/sof-qemu-run.py" --build-dir "${BUILD_DIR}" $VALGRIND_ARG | |
| python3 "${SCRIPT_DIR}/sof-qemu-run.py" --build-dir . $VALGRIND_ARG |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ SOF_DEFINE_REG_UUID(ipc_task_posix); | |
|
|
||
| static struct ipc *global_ipc; | ||
|
|
||
| #ifdef CONFIG_ARCH_POSIX_LIBFUZZER | ||
| // Not an ISR, called from the native_posix fuzz interrupt. Left | ||
| // alone for general hygiene. This is how a IPC interrupt would look | ||
| // if we had one. | ||
|
Comment on lines
+17
to
20
|
||
|
|
@@ -131,6 +132,7 @@ static void fuzz_isr(const void *arg) | |
|
|
||
| posix_ipc_isr(NULL); | ||
| } | ||
| #endif | ||
|
|
||
| // This API is... confounded by its history. With IPC3, the job of | ||
| // this function is to get a newly-received IPC message header (!) | ||
|
|
@@ -172,12 +174,14 @@ int ipc_platform_compact_read_msg(struct ipc_cmd_hdr *hdr, int words) | |
| // Re-raise the interrupt if there's still fuzz data to process | ||
| void ipc_platform_complete_cmd(struct ipc *ipc) | ||
| { | ||
| #ifdef CONFIG_ARCH_POSIX_LIBFUZZER | ||
| extern void posix_sw_set_pending_IRQ(unsigned int IRQn); | ||
|
|
||
| if (fuzz_in_sz > 0) { | ||
| posix_fuzz_sz = 0; | ||
| posix_sw_set_pending_IRQ(CONFIG_ZEPHYR_POSIX_FUZZ_IRQ); | ||
| } | ||
| #endif | ||
| } | ||
|
|
||
| int ipc_platform_send_msg(const struct ipc_msg *msg) | ||
|
|
@@ -200,8 +204,10 @@ void ipc_platform_send_msg_direct(const struct ipc_msg *msg) | |
|
|
||
| int platform_ipc_init(struct ipc *ipc) | ||
| { | ||
| #ifdef CONFIG_ARCH_POSIX_LIBFUZZER | ||
| IRQ_CONNECT(CONFIG_ZEPHYR_POSIX_FUZZ_IRQ, 0, fuzz_isr, NULL, 0); | ||
| irq_enable(CONFIG_ZEPHYR_POSIX_FUZZ_IRQ); | ||
| #endif | ||
|
|
||
| global_ipc = ipc; | ||
| schedule_task_init_edf(&ipc->ipc_task, SOF_UUID(ipc_task_posix_uuid), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
build_dir = os.path.abspath(args.build_dir)is resolved relative to the current working directory. Whensof-qemu-run.shdoescd "$BUILD_DIR"and still passes--build-dir "$BUILD_DIR"(typically a relative path likebuild-qemu_xtensa), this becomes<builddir>/build-qemu_xtensa, and the script will fail to findCMakeCache.txt/zephyr/. Either stopcd-ing in the shell wrapper, pass an absolute path (compute it beforecd), or have the Python script detect this case and fall back toos.getcwd()whenargs.build_dirdoesn’t point at a valid Zephyr build directory.