Tested Spimonitor with Emulated BMC master for write protected region.
diff --git a/target/ast10x0/board/src/spim_wiring.rs b/target/ast10x0/board/src/spim_wiring.rs index 1348917..f540d52 100644 --- a/target/ast10x0/board/src/spim_wiring.rs +++ b/target/ast10x0/board/src/spim_wiring.rs
@@ -339,7 +339,7 @@ let mut policy = profile::zephyr_default(); let _ = policy.add_region( 0, - 0x0800_0000, + 0x0010_0000, PrivilegeDirection::Write, PrivilegeOp::Disable, );
diff --git a/target/ast10x0/tests/spimonitor/BUILD.bazel b/target/ast10x0/tests/spimonitor/BUILD.bazel index 5d961b1..47f0d66 100644 --- a/target/ast10x0/tests/spimonitor/BUILD.bazel +++ b/target/ast10x0/tests/spimonitor/BUILD.bazel
@@ -1,12 +1,10 @@ # Licensed under the Apache-2.0 license # SPDX-License-Identifier: Apache-2.0 -load("@pigweed//pw_kernel/tooling:system_image.bzl", "system_image", "system_image_test") 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") +load(":spimonitor_test.bzl", "spimonitor_setup_all", "spimonitor_test") filegroup( name = "system_config", @@ -28,48 +26,20 @@ template = "//target/ast10x0:linker_script_template", ) -rust_binary( +spimonitor_test(1, TARGET_COMPATIBLE_WITH) +spimonitor_test(2, TARGET_COMPATIBLE_WITH) +spimonitor_test(3, TARGET_COMPATIBLE_WITH) +spimonitor_test(4, TARGET_COMPATIBLE_WITH) +spimonitor_setup_all(TARGET_COMPATIBLE_WITH) + +alias( name = "target", - srcs = ["target.rs"], - edition = "2024", - tags = ["kernel"], - target_compatible_with = TARGET_COMPATIBLE_WITH, - deps = [ - ":codegen", - ":linker_script", - "//target/ast10x0:entry", - "//target/ast10x0/board:ast10x0_board", - "//target/ast10x0/peripherals", - "@pigweed//pw_kernel/subsys/console:console_backend", - "@pigweed//pw_kernel/target:target_common", - "@pigweed//pw_log/rust:pw_log", - ], + actual = ":target_spim1", + visibility = ["//visibility:public"], ) -system_image( +alias( name = "spimonitor_test", - kernel = ":target", - platform = "//target/ast10x0", - system_config = ":system_config", - tags = ["kernel"], - target_compatible_with = TARGET_COMPATIBLE_WITH, - userspace = False, + actual = ":spimonitor1_test", visibility = ["//visibility:public"], ) - -system_image_test( - name = "spimonitor_evb_test", - image = ":spimonitor_test", - tags = ["hardware"], - target_compatible_with = select({ - "//target/ast10x0:qemu_enabled": ["@platforms//:incompatible"], - "//conditions:default": [], - }), - visibility = ["//visibility:public"], -) - -rust_binary_no_panics_test( - name = "no_panics_test", - binary = ":spimonitor_test", - tags = ["kernel"], -)
diff --git a/target/ast10x0/tests/spimonitor/setup_all_spim.rs b/target/ast10x0/tests/spimonitor/setup_all_spim.rs new file mode 100644 index 0000000..a041959 --- /dev/null +++ b/target/ast10x0/tests/spimonitor/setup_all_spim.rs
@@ -0,0 +1,142 @@ +// Licensed under the Apache-2.0 license +// SPDX-License-Identifier: Apache-2.0 + +//! Configure SPIM1 through SPIM4 and keep all monitors active. + +#![no_std] +#![no_main] + +use core::cell::UnsafeCell; + +#[path = "test_common.rs"] +mod test_common; + +use ast10x0_peripherals::scu::{ScuRegisters, SpiMonitorInstance}; +use ast10x0_peripherals::spimonitor::{ + MonitorPolicy, PrivilegeDirection, PrivilegeOp, SpiMonitorController, +}; +use target_common::{declare_target, TargetInterface}; +use {console_backend as _, entry as _}; + +struct Spim1Config; +struct Spim2Config; +struct Spim3Config; +struct Spim4Config; + +impl test_common::TestConfig for Spim1Config { + const INSTANCE: SpiMonitorInstance = SpiMonitorInstance::Spim0; + const CONTROLLER: SpiMonitorController = SpiMonitorController::Spim0; +} + +impl test_common::TestConfig for Spim2Config { + const INSTANCE: SpiMonitorInstance = SpiMonitorInstance::Spim1; + const CONTROLLER: SpiMonitorController = SpiMonitorController::Spim1; +} + +impl test_common::TestConfig for Spim3Config { + const INSTANCE: SpiMonitorInstance = SpiMonitorInstance::Spim2; + const CONTROLLER: SpiMonitorController = SpiMonitorController::Spim2; +} + +impl test_common::TestConfig for Spim4Config { + const INSTANCE: SpiMonitorInstance = SpiMonitorInstance::Spim3; + const CONTROLLER: SpiMonitorController = SpiMonitorController::Spim3; +} + +#[repr(align(16))] +struct LogRam(UnsafeCell<[u32; test_common::LOG_RAM_WORDS]>); + +// SAFETY: Each buffer is exclusively assigned to one SPIPF instance. +unsafe impl Sync for LogRam {} + +static SPIM1_LOG: LogRam = LogRam(UnsafeCell::new([0; test_common::LOG_RAM_WORDS])); +static SPIM2_LOG: LogRam = LogRam(UnsafeCell::new([0; test_common::LOG_RAM_WORDS])); +static SPIM3_LOG: LogRam = LogRam(UnsafeCell::new([0; test_common::LOG_RAM_WORDS])); +static SPIM4_LOG: LogRam = LogRam(UnsafeCell::new([0; test_common::LOG_RAM_WORDS])); + +const WRITE_PROTECTED_LENGTH: u32 = 0x0010_0000; +const ALLOW_COMMANDS: [u8; 32] = [ + 0x03, 0x13, 0x0b, 0x0c, 0x6b, 0x6c, 0x01, 0x05, 0x35, 0x06, 0x04, 0x20, 0x21, 0x9f, 0x5a, + 0xb7, 0xe9, 0x32, 0x34, 0xd8, 0xdc, 0x02, 0x12, 0x3b, 0x3c, 0x70, 0xbb, 0xbc, 0x50, 0xeb, + 0xec, 0xc2, +]; + +fn log_buffer(log: &'static LogRam) -> &'static mut [u32] { + // SAFETY: The caller assigns each static buffer to exactly one monitor. + unsafe { &mut *log.0.get() } +} + +fn production_policy() -> MonitorPolicy { + let mut policy = MonitorPolicy::empty(); + policy.allow_commands.copy_from_slice(&ALLOW_COMMANDS); + policy.allow_command_count = ALLOW_COMMANDS.len(); + let _ = policy.add_region( + 0, + WRITE_PROTECTED_LENGTH, + PrivilegeDirection::Write, + PrivilegeOp::Disable, + ); + policy +} + +fn setup_all_spim() -> Result<(), test_common::TestError> { + let scu = unsafe { ScuRegisters::new_global_unlocked() }; + let policy = production_policy(); + + pw_log::info!("=== SPIM1 ==="); + test_common::configure_wiring::<Spim1Config>(&scu)?; + let spim1 = test_common::initialize_monitor_with_policy::<Spim1Config>( + log_buffer(&SPIM1_LOG), + &policy, + )?; + test_common::dump_policy(&spim1, WRITE_PROTECTED_LENGTH)?; + let _spim1 = test_common::lock_monitor(spim1)?; + + pw_log::info!("=== SPIM2 ==="); + test_common::configure_wiring::<Spim2Config>(&scu)?; + let spim2 = test_common::initialize_monitor_with_policy::<Spim2Config>( + log_buffer(&SPIM2_LOG), + &policy, + )?; + test_common::dump_policy(&spim2, WRITE_PROTECTED_LENGTH)?; + let _spim2 = test_common::lock_monitor(spim2)?; + + pw_log::info!("=== SPIM3 ==="); + test_common::configure_wiring::<Spim3Config>(&scu)?; + let spim3 = test_common::initialize_monitor_with_policy::<Spim3Config>( + log_buffer(&SPIM3_LOG), + &policy, + )?; + test_common::dump_policy(&spim3, WRITE_PROTECTED_LENGTH)?; + let _spim3 = test_common::lock_monitor(spim3)?; + + pw_log::info!("=== SPIM4 ==="); + test_common::configure_wiring::<Spim4Config>(&scu)?; + let spim4 = test_common::initialize_monitor_with_policy::<Spim4Config>( + log_buffer(&SPIM4_LOG), + &policy, + )?; + test_common::dump_policy(&spim4, WRITE_PROTECTED_LENGTH)?; + let _spim4 = test_common::lock_monitor(spim4)?; + + pw_log::info!("All SPIM1-4 monitors are configured and locked"); + pw_log::info!("Firmware will remain active until the user stops or resets it"); + Ok(()) +} + +struct Target; + +impl TargetInterface for Target { + const NAME: &'static str = "AST10x0 Setup All External SPI Monitors"; + + fn main() -> ! { + if setup_all_spim().is_err() { + pw_log::info!("FAIL: setup all SPIM monitors"); + } + + #[expect(clippy::empty_loop)] + loop {} + } +} + +declare_target!(Target);
diff --git a/target/ast10x0/tests/spimonitor/spimonitor_test.bzl b/target/ast10x0/tests/spimonitor/spimonitor_test.bzl new file mode 100644 index 0000000..e229ed1 --- /dev/null +++ b/target/ast10x0/tests/spimonitor/spimonitor_test.bzl
@@ -0,0 +1,100 @@ +# Licensed under the Apache-2.0 license +# SPDX-License-Identifier: Apache-2.0 + +load("@pigweed//pw_kernel/tooling:system_image.bzl", "system_image", "system_image_test") +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") + +def spimonitor_test(index, target_compatible_with): + target_name = "target_spim{}".format(index) + image_name = "spimonitor{}_test".format(index) + + rust_binary( + name = target_name, + srcs = [ + "test_common.rs", + "test_spim{}.rs".format(index), + ], + crate_root = "test_spim{}.rs".format(index), + edition = "2024", + tags = ["kernel"], + target_compatible_with = target_compatible_with, + deps = [ + ":codegen", + ":linker_script", + "//target/ast10x0:entry", + "//target/ast10x0/board:ast10x0_board", + "//target/ast10x0/peripherals", + "@pigweed//pw_kernel/subsys/console:console_backend", + "@pigweed//pw_kernel/target:target_common", + "@pigweed//pw_log/rust:pw_log", + ], + ) + + system_image( + name = image_name, + kernel = ":" + target_name, + platform = "//target/ast10x0", + system_config = ":system_config", + tags = ["kernel"], + target_compatible_with = target_compatible_with, + userspace = False, + visibility = ["//visibility:public"], + ) + + system_image_test( + name = "spimonitor{}_evb_test".format(index), + image = ":" + image_name, + tags = ["hardware"], + target_compatible_with = select({ + "//target/ast10x0:qemu_enabled": ["@platforms//:incompatible"], + "//conditions:default": [], + }), + visibility = ["//visibility:public"], + ) + + rust_binary_no_panics_test( + name = "spimonitor{}_no_panics_test".format(index), + binary = ":" + image_name, + tags = ["kernel"], + ) + +def spimonitor_setup_all(target_compatible_with): + rust_binary( + name = "setup_all_spim", + srcs = [ + "setup_all_spim.rs", + "test_common.rs", + ], + crate_root = "setup_all_spim.rs", + edition = "2024", + tags = ["kernel"], + target_compatible_with = target_compatible_with, + deps = [ + ":codegen", + ":linker_script", + "//target/ast10x0:entry", + "//target/ast10x0/board:ast10x0_board", + "//target/ast10x0/peripherals", + "@pigweed//pw_kernel/subsys/console:console_backend", + "@pigweed//pw_kernel/target:target_common", + "@pigweed//pw_log/rust:pw_log", + ], + ) + + system_image( + name = "setup_all_spim_image", + kernel = ":setup_all_spim", + platform = "//target/ast10x0", + system_config = ":system_config", + tags = ["kernel"], + target_compatible_with = target_compatible_with, + userspace = False, + visibility = ["//visibility:public"], + ) + + rust_binary_no_panics_test( + name = "setup_all_spim_no_panics_test", + binary = ":setup_all_spim_image", + tags = ["kernel"], + )
diff --git a/target/ast10x0/tests/spimonitor/target.rs b/target/ast10x0/tests/spimonitor/test_common.rs similarity index 71% rename from target/ast10x0/tests/spimonitor/target.rs rename to target/ast10x0/tests/spimonitor/test_common.rs index 3792b23..d252f89 100644 --- a/target/ast10x0/tests/spimonitor/target.rs +++ b/target/ast10x0/tests/spimonitor/test_common.rs
@@ -1,10 +1,9 @@ // Licensed under the Apache-2.0 license // SPDX-License-Identifier: Apache-2.0 -//! AST10x0 SPI monitor configuration hardware test. +//! Shared AST10x0 external SPI monitor configuration tests. -#![no_std] -#![no_main] +#![allow(dead_code)] use core::cell::UnsafeCell; @@ -20,30 +19,29 @@ PrivilegeDirection, PrivilegeOp, SpiMonitor, SpiMonitorController, SpiMonitorError, Uninitialized, }; -use console_backend::console_backend_write_all; -use target_common::{declare_target, TargetInterface}; -use {console_backend as _, entry as _}; -pub struct Target {} - -const SPIM: SpiMonitorInstance = SpiMonitorInstance::Spim0; -const PROTECTED_LENGTH: u32 = 0x0010_0000; +pub const PROTECTED_LENGTH: u32 = 0x0010_0000; const LOG_RAM_BYTES: usize = 0x200; -const LOG_RAM_WORDS: usize = LOG_RAM_BYTES / core::mem::size_of::<u32>(); +pub const LOG_RAM_WORDS: usize = LOG_RAM_BYTES / core::mem::size_of::<u32>(); const COMMAND_VALID_MASK: u32 = (1 << 30) | (1 << 31); const COMMAND_LOCKED: u32 = 1 << 23; const LOCK_REQUIRED: u32 = (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 30) | (1 << 31); +pub trait TestConfig { + const INSTANCE: SpiMonitorInstance; + const CONTROLLER: SpiMonitorController; +} + #[repr(align(16))] struct LogRam(UnsafeCell<[u32; LOG_RAM_WORDS]>); -// SAFETY: This test is single-threaded and gives the buffer exclusively to SPIPF. +// SAFETY: Each test image is single-threaded and owns one SPIPF log buffer. unsafe impl Sync for LogRam {} static LOG_RAM: LogRam = LogRam(UnsafeCell::new([0; LOG_RAM_WORDS])); #[derive(Clone, Copy)] -enum TestError { +pub enum TestError { Monitor, Scu, Check, @@ -75,36 +73,34 @@ unsafe { &mut *LOG_RAM.0.get() } } -fn configure_wiring(scu: &ScuRegisters) -> Result<(), TestError> { +pub fn configure_wiring<C: TestConfig>(scu: &ScuRegisters) -> Result<(), TestError> { pw_log::info!("START: external monitor pinctrl, routing, and mux"); - apply_spim_pinctrl(scu, SPIM); - scu.disable_spim_cs_internal_pull_down(SPIM); + apply_spim_pinctrl(scu, C::INSTANCE); + scu.disable_spim_cs_internal_pull_down(C::INSTANCE); - // SPIPF observes external BMC/host traffic. Do not detour SPI1 or SPI2 - // internally into the monitor. + // SPIPF observes external BMC/host traffic. Do not detour SPI1 or SPI2. scu.set_spim_internal_mux(SpiMonitorSource::Spi1, 0)?; test_check!( scu.route_control_raw() & 0x0f == 0, "FAIL: internal SPI master detour is enabled" ); - // This SCU bit enables the SPIPF signal path. Controller bypass/filtering - // is controlled independently by SPIPF000[1:0]. - scu.set_spim_passthrough(SPIM, SpiMonitorPassthrough::Enabled); - scu.set_spim_miso_multi_func(SPIM, true); - scu.set_spim_filter(SPIM, true); + // SCU passthrough enables the external signal path through SPIPF. + scu.set_spim_passthrough(C::INSTANCE, SpiMonitorPassthrough::Enabled); + scu.set_spim_miso_multi_func(C::INSTANCE, true); + scu.set_spim_filter(C::INSTANCE, true); - apply_spim_external_mux(SPIM, ScuExtMuxSelect::Mux0); + apply_spim_external_mux(C::INSTANCE, ScuExtMuxSelect::Mux0); test_check!( - spim_external_mux_state(SPIM) == Some(ScuExtMuxSelect::Mux0), + spim_external_mux_state(C::INSTANCE) == Some(ScuExtMuxSelect::Mux0), "FAIL: external mux 0 GPIO readback" ); - apply_spim_external_mux(SPIM, ScuExtMuxSelect::Mux1); + apply_spim_external_mux(C::INSTANCE, ScuExtMuxSelect::Mux1); test_check!( - spim_external_mux_state(SPIM) == Some(ScuExtMuxSelect::Mux1), + spim_external_mux_state(C::INSTANCE) == Some(ScuExtMuxSelect::Mux1), "FAIL: external mux 1 GPIO readback" ); - scu.set_spim_ext_mux(SPIM, ScuExtMuxSelect::Mux1); + scu.set_spim_ext_mux(C::INSTANCE, ScuExtMuxSelect::Mux1); test_check!( scu.route_control_raw() & 0x0f == 0, @@ -114,7 +110,7 @@ Ok(()) } -fn build_policy() -> MonitorPolicy { +pub fn build_policy() -> MonitorPolicy { let mut policy = MonitorPolicy::empty(); policy.allow_commands[..9] .copy_from_slice(&[0x9f, 0x05, 0x06, 0x04, 0x02, 0x12, 0x20, 0x21, 0x0c]); @@ -128,22 +124,31 @@ policy } -fn initialize_monitor() -> Result<ConfiguredSpiMonitor, TestError> { +pub fn initialize_monitor<C: TestConfig>( + buffer: &'static mut [u32], +) -> Result<ConfiguredSpiMonitor, TestError> { + initialize_monitor_with_policy::<C>(buffer, &build_policy()) +} + +pub fn initialize_monitor_with_policy<C: TestConfig>( + buffer: &'static mut [u32], + policy: &MonitorPolicy, +) -> Result<ConfiguredSpiMonitor, TestError> { pw_log::info!("START: monitor reset, policy, and log RAM"); - let monitor = unsafe { SpiMonitor::<Uninitialized>::new(SpiMonitorController::Spim0) }; + let monitor = unsafe { SpiMonitor::<Uninitialized>::new(C::CONTROLLER) }; monitor.software_reset(); test_check!( monitor.regs().read_ctrl() & (1 << 15) == 0, "FAIL: software reset did not deassert" ); - let configured = monitor.apply_policy(&build_policy())?; + let configured = monitor.apply_policy(policy)?; test_check!( configured.state() == MonitorState::Configured, "FAIL: monitor did not enter configured state" ); - configured.configure_log(log_buffer())?; + configured.configure_log(buffer)?; test_check!( configured.regs().read_log_capacity_entries() as usize == LOG_RAM_WORDS, "FAIL: 0x200-byte log RAM configuration" @@ -164,6 +169,38 @@ Ok(configured) } +#[allow(dead_code)] +pub fn dump_policy( + configured: &ConfiguredSpiMonitor, + write_protected_length: u32, +) -> Result<(), TestError> { + pw_log::info!("allow-command table:"); + for slot in 0..32 { + let value = configured.regs().read_allow_cmd_slot(slot); + if value != 0 { + pw_log::info!( + " slot {:02}: cmd=0x{:02x}, raw=0x{:08x}", + slot as u32, + (value & 0xff) as u32, + value as u32 + ); + } + } + + pw_log::info!( + "write-protected region: start=0x00000000, length=0x{:08x}", + write_protected_length as u32 + ); + Ok(()) +} + +#[allow(dead_code)] +pub fn lock_monitor( + configured: ConfiguredSpiMonitor, +) -> Result<ast10x0_peripherals::spimonitor::LockedSpiMonitor, TestError> { + Ok(configured.lock()?) +} + fn test_passthrough_control(configured: &ConfiguredSpiMonitor) -> Result<(), TestError> { pw_log::info!("START: passthrough control readback"); configured.set_passthrough(PassthroughMode::Enabled); @@ -239,12 +276,12 @@ Ok(()) } -fn run_spimonitor_test() -> Result<(), TestError> { +pub fn run<C: TestConfig>() -> Result<(), TestError> { pw_log::info!("=== AST10x0 external SPI monitor configuration test ==="); let scu = unsafe { ScuRegisters::new_global_unlocked() }; - configure_wiring(&scu)?; - let configured = initialize_monitor()?; + configure_wiring::<C>(&scu)?; + let configured = initialize_monitor::<C>(log_buffer())?; test_passthrough_control(&configured)?; test_command_policy(&configured)?; test_address_policy(&configured)?; @@ -254,21 +291,3 @@ pw_log::info!("=== all SPI monitor configuration tests passed ==="); Ok(()) } - -impl TargetInterface for Target { - const NAME: &'static str = "AST10x0 External SPI Monitor Configuration Test"; - - fn main() -> ! { - let sentinel = if run_spimonitor_test().is_ok() { - b"TEST_RESULT:PASS\n" - } else { - b"TEST_RESULT:FAIL\n" - }; - let _ = console_backend_write_all(sentinel); - - #[expect(clippy::empty_loop)] - loop {} - } -} - -declare_target!(Target);
diff --git a/target/ast10x0/tests/spimonitor/test_spim1.rs b/target/ast10x0/tests/spimonitor/test_spim1.rs new file mode 100644 index 0000000..0aa6a20 --- /dev/null +++ b/target/ast10x0/tests/spimonitor/test_spim1.rs
@@ -0,0 +1,40 @@ +// Licensed under the Apache-2.0 license +// SPDX-License-Identifier: Apache-2.0 + +#![no_std] +#![no_main] + +#[path = "test_common.rs"] +mod test_common; + +use ast10x0_peripherals::scu::SpiMonitorInstance; +use ast10x0_peripherals::spimonitor::SpiMonitorController; +use console_backend::console_backend_write_all; +use target_common::{declare_target, TargetInterface}; +use {console_backend as _, entry as _}; + +struct Spim1Config; + +impl test_common::TestConfig for Spim1Config { + const INSTANCE: SpiMonitorInstance = SpiMonitorInstance::Spim0; + const CONTROLLER: SpiMonitorController = SpiMonitorController::Spim0; +} + +struct Target; + +impl TargetInterface for Target { + const NAME: &'static str = "AST10x0 External SPIM1 Configuration Test"; + + fn main() -> ! { + let sentinel = if test_common::run::<Spim1Config>().is_ok() { + b"TEST_RESULT:PASS\n" + } else { + b"TEST_RESULT:FAIL\n" + }; + let _ = console_backend_write_all(sentinel); + #[expect(clippy::empty_loop)] + loop {} + } +} + +declare_target!(Target);
diff --git a/target/ast10x0/tests/spimonitor/test_spim2.rs b/target/ast10x0/tests/spimonitor/test_spim2.rs new file mode 100644 index 0000000..cae247c --- /dev/null +++ b/target/ast10x0/tests/spimonitor/test_spim2.rs
@@ -0,0 +1,40 @@ +// Licensed under the Apache-2.0 license +// SPDX-License-Identifier: Apache-2.0 + +#![no_std] +#![no_main] + +#[path = "test_common.rs"] +mod test_common; + +use ast10x0_peripherals::scu::SpiMonitorInstance; +use ast10x0_peripherals::spimonitor::SpiMonitorController; +use console_backend::console_backend_write_all; +use target_common::{declare_target, TargetInterface}; +use {console_backend as _, entry as _}; + +struct Spim2Config; + +impl test_common::TestConfig for Spim2Config { + const INSTANCE: SpiMonitorInstance = SpiMonitorInstance::Spim1; + const CONTROLLER: SpiMonitorController = SpiMonitorController::Spim1; +} + +struct Target; + +impl TargetInterface for Target { + const NAME: &'static str = "AST10x0 External SPIM2 Configuration Test"; + + fn main() -> ! { + let sentinel = if test_common::run::<Spim2Config>().is_ok() { + b"TEST_RESULT:PASS\n" + } else { + b"TEST_RESULT:FAIL\n" + }; + let _ = console_backend_write_all(sentinel); + #[expect(clippy::empty_loop)] + loop {} + } +} + +declare_target!(Target);
diff --git a/target/ast10x0/tests/spimonitor/test_spim3.rs b/target/ast10x0/tests/spimonitor/test_spim3.rs new file mode 100644 index 0000000..e6ce159 --- /dev/null +++ b/target/ast10x0/tests/spimonitor/test_spim3.rs
@@ -0,0 +1,40 @@ +// Licensed under the Apache-2.0 license +// SPDX-License-Identifier: Apache-2.0 + +#![no_std] +#![no_main] + +#[path = "test_common.rs"] +mod test_common; + +use ast10x0_peripherals::scu::SpiMonitorInstance; +use ast10x0_peripherals::spimonitor::SpiMonitorController; +use console_backend::console_backend_write_all; +use target_common::{declare_target, TargetInterface}; +use {console_backend as _, entry as _}; + +struct Spim3Config; + +impl test_common::TestConfig for Spim3Config { + const INSTANCE: SpiMonitorInstance = SpiMonitorInstance::Spim2; + const CONTROLLER: SpiMonitorController = SpiMonitorController::Spim2; +} + +struct Target; + +impl TargetInterface for Target { + const NAME: &'static str = "AST10x0 External SPIM3 Configuration Test"; + + fn main() -> ! { + let sentinel = if test_common::run::<Spim3Config>().is_ok() { + b"TEST_RESULT:PASS\n" + } else { + b"TEST_RESULT:FAIL\n" + }; + let _ = console_backend_write_all(sentinel); + #[expect(clippy::empty_loop)] + loop {} + } +} + +declare_target!(Target);
diff --git a/target/ast10x0/tests/spimonitor/test_spim4.rs b/target/ast10x0/tests/spimonitor/test_spim4.rs new file mode 100644 index 0000000..3d43715 --- /dev/null +++ b/target/ast10x0/tests/spimonitor/test_spim4.rs
@@ -0,0 +1,40 @@ +// Licensed under the Apache-2.0 license +// SPDX-License-Identifier: Apache-2.0 + +#![no_std] +#![no_main] + +#[path = "test_common.rs"] +mod test_common; + +use ast10x0_peripherals::scu::SpiMonitorInstance; +use ast10x0_peripherals::spimonitor::SpiMonitorController; +use console_backend::console_backend_write_all; +use target_common::{declare_target, TargetInterface}; +use {console_backend as _, entry as _}; + +struct Spim4Config; + +impl test_common::TestConfig for Spim4Config { + const INSTANCE: SpiMonitorInstance = SpiMonitorInstance::Spim3; + const CONTROLLER: SpiMonitorController = SpiMonitorController::Spim3; +} + +struct Target; + +impl TargetInterface for Target { + const NAME: &'static str = "AST10x0 External SPIM4 Configuration Test"; + + fn main() -> ! { + let sentinel = if test_common::run::<Spim4Config>().is_ok() { + b"TEST_RESULT:PASS\n" + } else { + b"TEST_RESULT:FAIL\n" + }; + let _ = console_backend_write_all(sentinel); + #[expect(clippy::empty_loop)] + loop {} + } +} + +declare_target!(Target);