pw stress work in progress
diff --git a/target/ast10x0/tests/stress/BUILD.bazel b/target/ast10x0/tests/stress/BUILD.bazel
new file mode 100644
index 0000000..2831344
--- /dev/null
+++ b/target/ast10x0/tests/stress/BUILD.bazel
@@ -0,0 +1,4 @@
+# Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
+
+package(default_visibility = ["//visibility:public"])
diff --git a/target/ast10x0/tests/stress/ipc/user/BUILD.bazel b/target/ast10x0/tests/stress/ipc/user/BUILD.bazel
new file mode 100644
index 0000000..2510ac1
--- /dev/null
+++ b/target/ast10x0/tests/stress/ipc/user/BUILD.bazel
@@ -0,0 +1,67 @@
+# Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
+
+load("@pigweed//pw_kernel/tooling:system_image.bzl", "system_image")
+load("@pigweed//pw_kernel/tooling:target_codegen.bzl", "target_codegen")
+load("@pigweed//pw_kernel/tooling:target_linker_script.bzl", "target_linker_script")
+load("@pigweed//pw_kernel/tooling/panic_detector:rust_binary_no_panics_test.bzl", "rust_binary_no_panics_test")
+load("@rules_rust//rust:defs.bzl", "rust_binary")
+load("//target/ast10x0:defs.bzl", "TARGET_COMPATIBLE_WITH")
+
+system_image(
+    name = "ipc",
+    apps = [
+        "@pigweed//pw_kernel/tests/stress/ipc/user:initiator",
+        "@pigweed//pw_kernel/tests/stress/ipc/user:handler",
+    ],
+    kernel = ":target",
+    platform = "//target/ast10x0",
+    system_config = ":system_config",
+    tags = ["kernel"],
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+)
+
+rust_binary_no_panics_test(
+    name = "no_panics_test",
+    binary = ":ipc",
+    tags = ["kernel"],
+)
+
+filegroup(
+    name = "system_config",
+    srcs = ["system.json5"],
+)
+
+target_codegen(
+    name = "codegen",
+    arch = "@pigweed//pw_kernel/arch/arm_cortex_m:arch_arm_cortex_m",
+    system_config = ":system_config",
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+)
+
+target_linker_script(
+    name = "linker_script",
+    system_config = ":system_config",
+    tags = ["kernel"],
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+    template = "//target/ast10x0:linker_script_template",
+)
+
+rust_binary(
+    name = "target",
+    srcs = ["target.rs"],
+    edition = "2024",
+    tags = ["kernel"],
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+    deps = [
+        ":codegen",
+        ":linker_script",
+        "//target/ast10x0:entry",
+        "@pigweed//pw_kernel/arch/arm_cortex_m:arch_arm_cortex_m",
+        "@pigweed//pw_kernel/kernel",
+        "@pigweed//pw_kernel/subsys/console:console_backend",
+        "@pigweed//pw_kernel/target:target_common",
+        "@pigweed//pw_kernel/userspace",
+        "@pigweed//pw_log/rust:pw_log",
+    ],
+)
diff --git a/target/ast10x0/tests/stress/ipc/user/system.json5 b/target/ast10x0/tests/stress/ipc/user/system.json5
new file mode 100644
index 0000000..1349b8e
--- /dev/null
+++ b/target/ast10x0/tests/stress/ipc/user/system.json5
@@ -0,0 +1,75 @@
+// Licensed under the Apache-2.0 license
+// SPDX-License-Identifier: Apache-2.0
+
+// AST10x0 IPC Stress Test Configuration
+// Two separate apps: initiator sends characters over IPC, handler uppercases
+// and echoes them back. Both loop indefinitely.
+//
+// Memory layout:
+//   0x00000000 - 0x00000500: Vector table (1280 bytes)
+//   0x00000500 - 0x00020000: Kernel code (~126KB, ends at 128KB boundary)
+//   0x00020000 - 0x00040000: initiator app flash (128KB)
+//   0x00040000 - 0x00060000: handler app flash (128KB)
+//   0x00060000 - 0x00080000: Kernel RAM (128KB)
+//   0x00080000 - 0x000A0000: App RAM (2 x 64KB)
+{
+    arch: {
+        type: "armv7m",
+        vector_table_start_address: 0x00000000,
+        vector_table_size_bytes: 1280,  // 0x500
+    },
+    kernel: {
+        flash_start_address: 0x00000500,
+        flash_size_bytes: 129792,         // ~126KB (ends at 0x00020000)
+        ram_start_address: 0x00060000,
+        ram_size_bytes: 131072,           // 128KB
+    },
+    apps: [
+        {
+            name: "initiator",
+            flash_size_bytes: 131072,     // 128KB
+            processes: [
+                {
+                    name: "initiator_process",
+                    ram_size_bytes: 65536,        // 64KB
+                    objects: [
+                        {
+                            name: "ipc",
+                            type: "channel_initiator",
+                            handler_process: "handler_process",
+                            handler_object_name: "ipc",
+                        },
+                    ],
+                    threads: [
+                        {
+                            name: "initiator_thread",
+                            kernel_stack_size_bytes: 2048,
+                        },
+                    ],
+                },
+            ],
+        },
+        {
+            name: "handler",
+            flash_size_bytes: 131072,     // 128KB
+            processes: [
+                {
+                    name: "handler_process",
+                    ram_size_bytes: 65536,        // 64KB
+                    objects: [
+                        {
+                            name: "ipc",
+                            type: "channel_handler",
+                        },
+                    ],
+                    threads: [
+                        {
+                            name: "handler_thread",
+                            kernel_stack_size_bytes: 2048,
+                        },
+                    ],
+                },
+            ],
+        },
+    ],
+}
diff --git a/target/ast10x0/tests/stress/ipc/user/target.rs b/target/ast10x0/tests/stress/ipc/user/target.rs
new file mode 100644
index 0000000..c5a38b9
--- /dev/null
+++ b/target/ast10x0/tests/stress/ipc/user/target.rs
@@ -0,0 +1,31 @@
+// Licensed under the Apache-2.0 license
+// SPDX-License-Identifier: Apache-2.0
+
+#![no_std]
+#![no_main]
+
+use console_backend::console_backend_write_all;
+use entry as _;
+use target_common::{TargetInterface, declare_target};
+
+pub struct Target {}
+
+impl TargetInterface for Target {
+    const NAME: &'static str = "AST10x0 IPC Stress";
+
+    fn main() -> ! {
+        codegen::start();
+        #[expect(clippy::empty_loop)]
+        loop {}
+    }
+
+    fn shutdown(code: u32) -> ! {
+        if code != 0 {
+            let _ = console_backend_write_all(b"TEST_RESULT:FAIL\n");
+        }
+        #[expect(clippy::empty_loop)]
+        loop {}
+    }
+}
+
+declare_target!(Target);
diff --git a/target/ast10x0/tests/stress/mutex/kernel/BUILD.bazel b/target/ast10x0/tests/stress/mutex/kernel/BUILD.bazel
new file mode 100644
index 0000000..adc3068
--- /dev/null
+++ b/target/ast10x0/tests/stress/mutex/kernel/BUILD.bazel
@@ -0,0 +1,56 @@
+# Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
+
+load("@pigweed//pw_kernel/tooling:system_image.bzl", "system_image")
+load("@pigweed//pw_kernel/tooling:target_linker_script.bzl", "target_linker_script")
+load("@pigweed//pw_kernel/tooling/panic_detector:rust_binary_no_panics_test.bzl", "rust_binary_no_panics_test")
+load("@rules_rust//rust:defs.bzl", "rust_binary")
+load("//target/ast10x0:defs.bzl", "TARGET_COMPATIBLE_WITH")
+
+system_image(
+    name = "mutex",
+    kernel = ":target",
+    platform = "//target/ast10x0",
+    system_config = ":system_config",
+    tags = ["kernel"],
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+    userspace = False,
+)
+
+rust_binary_no_panics_test(
+    name = "no_panics_test",
+    binary = ":mutex",
+    tags = ["kernel"],
+)
+
+filegroup(
+    name = "system_config",
+    srcs = ["system.json5"],
+)
+
+target_linker_script(
+    name = "linker_script",
+    system_config = ":system_config",
+    tags = ["kernel"],
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+    template = "//target/ast10x0:linker_script_template",
+)
+
+rust_binary(
+    name = "target",
+    srcs = ["target.rs"],
+    edition = "2024",
+    tags = ["kernel"],
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+    deps = [
+        ":linker_script",
+        "//target/ast10x0:config",
+        "//target/ast10x0:console",
+        "//target/ast10x0:entry",
+        "@pigweed//pw_kernel/arch/arm_cortex_m:arch_arm_cortex_m",
+        "@pigweed//pw_kernel/kernel",
+        "@pigweed//pw_kernel/target:target_common",
+        "@pigweed//pw_kernel/tests/stress/mutex/kernel:mutex",
+        "@pigweed//pw_log/rust:pw_log",
+    ],
+)
diff --git a/target/ast10x0/tests/stress/mutex/kernel/system.json5 b/target/ast10x0/tests/stress/mutex/kernel/system.json5
new file mode 100644
index 0000000..56ff708
--- /dev/null
+++ b/target/ast10x0/tests/stress/mutex/kernel/system.json5
@@ -0,0 +1,19 @@
+// Licensed under the Apache-2.0 license
+// SPDX-License-Identifier: Apache-2.0
+
+// AST10x0 Kernel Mutex Stress Test Configuration
+// Kernel-only image; three threads contend on a single mutex indefinitely.
+// Memory layout matches threads/kernel — kernel occupies all available RAM.
+{
+    arch: {
+        type: "armv7m",
+        vector_table_start_address: 0x00000000,
+        vector_table_size_bytes: 1280,  // 0x500 (320 vectors)
+    },
+    kernel: {
+        flash_start_address: 0x00000500,  // After vector table
+        flash_size_bytes: 262144,         // 256KB for kernel code
+        ram_start_address: 0x00040500,    // RAM starts after code
+        ram_size_bytes: 393216,           // 384KB for data
+    },
+}
diff --git a/target/ast10x0/tests/stress/mutex/kernel/target.rs b/target/ast10x0/tests/stress/mutex/kernel/target.rs
new file mode 100644
index 0000000..1d84fb9
--- /dev/null
+++ b/target/ast10x0/tests/stress/mutex/kernel/target.rs
@@ -0,0 +1,36 @@
+// Licensed under the Apache-2.0 license
+// SPDX-License-Identifier: Apache-2.0
+
+#![no_std]
+#![no_main]
+
+use arch_arm_cortex_m::Arch;
+use console_backend::console_backend_write_all;
+use entry as _;
+use target_common::{TargetInterface, declare_target};
+
+pub struct Target {}
+
+impl TargetInterface for Target {
+    const NAME: &'static str = "AST10x0 Kernel Mutex Stress";
+
+    fn main() -> ! {
+        static mut APP_STATE: mutex::AppState<Arch> = mutex::AppState::new(Arch);
+        // SAFETY: `main` is only executed once, so we never generate more
+        // than one `&mut` reference to `APP_STATE`.
+        #[expect(static_mut_refs)]
+        let _ = mutex::main(Arch, unsafe { &mut APP_STATE });
+        #[expect(clippy::empty_loop)]
+        loop {}
+    }
+
+    fn shutdown(code: u32) -> ! {
+        if code != 0 {
+            let _ = console_backend_write_all(b"TEST_RESULT:FAIL\n");
+        }
+        #[expect(clippy::empty_loop)]
+        loop {}
+    }
+}
+
+declare_target!(Target);
diff --git a/target/ast10x0/tests/stress/process_termination/user/BUILD.bazel b/target/ast10x0/tests/stress/process_termination/user/BUILD.bazel
new file mode 100644
index 0000000..0a30fba
--- /dev/null
+++ b/target/ast10x0/tests/stress/process_termination/user/BUILD.bazel
@@ -0,0 +1,67 @@
+# Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
+
+load("@pigweed//pw_kernel/tooling:system_image.bzl", "system_image")
+load("@pigweed//pw_kernel/tooling:target_codegen.bzl", "target_codegen")
+load("@pigweed//pw_kernel/tooling:target_linker_script.bzl", "target_linker_script")
+load("@pigweed//pw_kernel/tooling/panic_detector:rust_binary_no_panics_test.bzl", "rust_binary_no_panics_test")
+load("@rules_rust//rust:defs.bzl", "rust_binary")
+load("//target/ast10x0:defs.bzl", "TARGET_COMPATIBLE_WITH")
+
+system_image(
+    name = "process_termination",
+    apps = [
+        "@pigweed//pw_kernel/tests/stress/process_termination/user:main",
+        "@pigweed//pw_kernel/tests/stress/process_termination/user:forced_exit",
+    ],
+    kernel = ":target",
+    platform = "//target/ast10x0",
+    system_config = ":system_config",
+    tags = ["kernel"],
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+)
+
+rust_binary_no_panics_test(
+    name = "no_panics_test",
+    binary = ":process_termination",
+    tags = ["kernel"],
+)
+
+filegroup(
+    name = "system_config",
+    srcs = ["system.json5"],
+)
+
+target_codegen(
+    name = "codegen",
+    arch = "@pigweed//pw_kernel/arch/arm_cortex_m:arch_arm_cortex_m",
+    system_config = ":system_config",
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+)
+
+target_linker_script(
+    name = "linker_script",
+    system_config = ":system_config",
+    tags = ["kernel"],
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+    template = "//target/ast10x0:linker_script_template",
+)
+
+rust_binary(
+    name = "target",
+    srcs = ["target.rs"],
+    edition = "2024",
+    tags = ["kernel"],
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+    deps = [
+        ":codegen",
+        ":linker_script",
+        "//target/ast10x0:entry",
+        "@pigweed//pw_kernel/arch/arm_cortex_m:arch_arm_cortex_m",
+        "@pigweed//pw_kernel/kernel",
+        "@pigweed//pw_kernel/subsys/console:console_backend",
+        "@pigweed//pw_kernel/target:target_common",
+        "@pigweed//pw_kernel/userspace",
+        "@pigweed//pw_log/rust:pw_log",
+    ],
+)
diff --git a/target/ast10x0/tests/stress/process_termination/user/system.json5 b/target/ast10x0/tests/stress/process_termination/user/system.json5
new file mode 100644
index 0000000..c3485f6
--- /dev/null
+++ b/target/ast10x0/tests/stress/process_termination/user/system.json5
@@ -0,0 +1,73 @@
+// Licensed under the Apache-2.0 license
+// SPDX-License-Identifier: Apache-2.0
+
+// AST10x0 Process Termination Stress Test Configuration
+// Two apps: main repeatedly terminates and restarts forced_exit indefinitely.
+// main holds a process handle to forced_exit's "extra" process, which is
+// named to match the #[process_entry("extra")] in forced_exit.rs.
+//
+// Memory layout:
+//   0x00000000 - 0x00000500: Vector table (1280 bytes)
+//   0x00000500 - 0x00020000: Kernel code (~126KB, ends at 128KB boundary)
+//   0x00020000 - 0x00040000: main app flash (128KB)
+//   0x00040000 - 0x00060000: forced_exit app flash (128KB)
+//   0x00060000 - 0x00080000: Kernel RAM (128KB)
+//   0x00080000 - 0x000A0000: App RAM (main 64KB, forced_exit 64KB)
+{
+    arch: {
+        type: "armv7m",
+        vector_table_start_address: 0x00000000,
+        vector_table_size_bytes: 1280,  // 0x500
+    },
+    kernel: {
+        flash_start_address: 0x00000500,
+        flash_size_bytes: 129792,         // ~126KB (ends at 0x00020000)
+        ram_start_address: 0x00060000,
+        ram_size_bytes: 131072,           // 128KB
+    },
+    apps: [
+        {
+            name: "main",
+            flash_size_bytes: 131072,     // 128KB
+            processes: [
+                {
+                    name: "main_process",
+                    ram_size_bytes: 65536,        // 64KB
+                    objects: [
+                        {
+                            // Generates handle::FORCED_EXIT_PROCESS in main_codegen.
+                            // linked_process must match the process name in the
+                            // forced_exit app ("extra" from #[process_entry("extra")]).
+                            name: "forced_exit_process",
+                            type: "process",
+                            linked_process: "extra",
+                        },
+                    ],
+                    threads: [
+                        {
+                            name: "main_thread",
+                            kernel_stack_size_bytes: 2048,
+                        },
+                    ],
+                },
+            ],
+        },
+        {
+            name: "forced_exit",
+            flash_size_bytes: 131072,     // 128KB
+            processes: [
+                {
+                    // Name must match #[process_entry("extra")] in forced_exit.rs.
+                    name: "extra",
+                    ram_size_bytes: 65536,        // 64KB
+                    threads: [
+                        {
+                            name: "extra_thread",
+                            kernel_stack_size_bytes: 2048,
+                        },
+                    ],
+                },
+            ],
+        },
+    ],
+}
diff --git a/target/ast10x0/tests/stress/process_termination/user/target.rs b/target/ast10x0/tests/stress/process_termination/user/target.rs
new file mode 100644
index 0000000..43af741
--- /dev/null
+++ b/target/ast10x0/tests/stress/process_termination/user/target.rs
@@ -0,0 +1,31 @@
+// Licensed under the Apache-2.0 license
+// SPDX-License-Identifier: Apache-2.0
+
+#![no_std]
+#![no_main]
+
+use console_backend::console_backend_write_all;
+use entry as _;
+use target_common::{TargetInterface, declare_target};
+
+pub struct Target {}
+
+impl TargetInterface for Target {
+    const NAME: &'static str = "AST10x0 Process Termination Stress";
+
+    fn main() -> ! {
+        codegen::start();
+        #[expect(clippy::empty_loop)]
+        loop {}
+    }
+
+    fn shutdown(code: u32) -> ! {
+        if code != 0 {
+            let _ = console_backend_write_all(b"TEST_RESULT:FAIL\n");
+        }
+        #[expect(clippy::empty_loop)]
+        loop {}
+    }
+}
+
+declare_target!(Target);