fixed merge clipping issue
diff --git a/target/ast10x0/peripherals/BUILD.bazel b/target/ast10x0/peripherals/BUILD.bazel index 509b5d5..08a0b72 100644 --- a/target/ast10x0/peripherals/BUILD.bazel +++ b/target/ast10x0/peripherals/BUILD.bazel
@@ -51,8 +51,8 @@ "smc/spi/spi.rs", "smc/spi/spi_transaction.rs", "smc/types.rs", - "spimonitor/controller.rs", "spimonitor/commands.rs", + "spimonitor/controller.rs", "spimonitor/mod.rs", "spimonitor/policy.rs", "spimonitor/profile.rs", @@ -86,4 +86,9 @@ srcs = ["spimonitor/commands.rs"], crate_name = "spimonitor_commands_test", edition = "2024", + tags = ["do_not_build"], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], )
diff --git a/target/ast10x0/peripherals/smc/controller.rs b/target/ast10x0/peripherals/smc/controller.rs index bef0003..545b028 100644 --- a/target/ast10x0/peripherals/smc/controller.rs +++ b/target/ast10x0/peripherals/smc/controller.rs
@@ -618,8 +618,7 @@ let reg = self.regs.read_cs_ctrl(cs); self.regs .write_cs_ctrl(cs, (reg & !SPI_CTRL_FREQ_MASK) | encoded_div); - self.normal_read_ctrl[cs_idx] = self.regs.read_cs_ctrl(cs); - + self.set_normal_read_ctrl(cs, self.regs.read_cs_ctrl(cs)); Ok(()) }
diff --git a/target/ast10x0/peripherals/spimonitor/commands.rs b/target/ast10x0/peripherals/spimonitor/commands.rs index 1024cbf..aa71f77 100644 --- a/target/ast10x0/peripherals/spimonitor/commands.rs +++ b/target/ast10x0/peripherals/spimonitor/commands.rs
@@ -34,12 +34,60 @@ } } -const fn command( - opcode: u8, +#[derive(Clone, Copy)] +struct CommandFlags { generic: bool, write: bool, read: bool, memory: bool, +} + +const GENERIC_READ_MEMORY: CommandFlags = CommandFlags { + generic: true, + write: false, + read: true, + memory: true, +}; +const GENERIC_WRITE_MEMORY: CommandFlags = CommandFlags { + generic: true, + write: true, + read: false, + memory: true, +}; +const GENERIC_NONE: CommandFlags = CommandFlags { + generic: true, + write: false, + read: false, + memory: false, +}; +const GENERIC_READ: CommandFlags = CommandFlags { + generic: true, + write: false, + read: true, + memory: false, +}; +const GENERIC_WRITE: CommandFlags = CommandFlags { + generic: true, + write: true, + read: false, + memory: false, +}; +const RESERVED_NONE: CommandFlags = CommandFlags { + generic: false, + write: false, + read: false, + memory: false, +}; +const RESERVED_WRITE: CommandFlags = CommandFlags { + generic: false, + write: true, + read: false, + memory: false, +}; + +const fn command( + opcode: u8, + flags: CommandFlags, data_width: u8, dummy_cycles: u8, program_size: u8, @@ -48,10 +96,10 @@ ) -> CommandDescriptor { CommandDescriptor { opcode, - generic, - write, - read, - memory, + generic: flags.generic, + write: flags.write, + read: flags.read, + memory: flags.memory, data_width, dummy_cycles, program_size, @@ -64,37 +112,33 @@ #[must_use] pub const fn descriptor(opcode: u8) -> Option<CommandDescriptor> { let entry = match opcode { - 0x03 => command(opcode, true, false, true, true, 1, 0, 0, 3, 1), - 0x13 => command(opcode, true, false, true, true, 1, 0, 0, 4, 1), - 0x0b => command(opcode, true, false, true, true, 1, 8, 0, 3, 1), - 0x0c => command(opcode, true, false, true, true, 1, 8, 0, 4, 1), - 0x3b => command(opcode, true, false, true, true, 2, 8, 0, 3, 1), - 0x3c => command(opcode, true, false, true, true, 2, 8, 0, 4, 1), - 0xbb => command(opcode, true, false, true, true, 2, 4, 0, 3, 2), - 0xbc => command(opcode, true, false, true, true, 2, 4, 0, 4, 2), - 0x6b => command(opcode, true, false, true, true, 3, 8, 0, 3, 1), - 0x6c => command(opcode, true, false, true, true, 3, 8, 0, 4, 1), - 0xeb => command(opcode, true, false, true, true, 3, 6, 0, 3, 3), - 0xec => command(opcode, true, false, true, true, 3, 6, 0, 4, 3), - 0x02 => command(opcode, true, true, false, true, 1, 0, 1, 3, 1), - 0x12 => command(opcode, true, true, false, true, 1, 0, 1, 4, 1), - 0x32 => command(opcode, true, true, false, true, 3, 0, 1, 3, 1), - 0x34 => command(opcode, true, true, false, true, 3, 0, 1, 4, 1), - 0x20 => command(opcode, true, true, false, true, 0, 0, 1, 3, 1), - 0x21 => command(opcode, true, true, false, true, 0, 0, 1, 4, 1), - 0xd8 => command(opcode, true, true, false, true, 0, 0, 5, 3, 1), - 0xdc => command(opcode, true, true, false, true, 0, 0, 5, 4, 1), - 0x06 | 0x04 | 0x50 | 0x66 | 0x99 => { - command(opcode, true, false, false, false, 0, 0, 0, 0, 0) - } - 0x05 | 0x35 | 0x15 | 0x70 | 0x9f => { - command(opcode, true, false, true, false, 1, 0, 0, 0, 0) - } - 0x01 | 0x31 => command(opcode, true, true, false, false, 1, 0, 0, 0, 0), - 0x5a => command(opcode, true, false, true, false, 1, 8, 0, 3, 1), - 0xb7 | 0xe9 => command(opcode, false, false, false, false, 0, 0, 0, 0, 0), - 0xc5 => command(opcode, false, true, false, false, 1, 0, 0, 0, 0), - 0xc2 => command(opcode, true, true, false, false, 1, 0, 0, 0, 0), + 0x03 => command(opcode, GENERIC_READ_MEMORY, 1, 0, 0, 3, 1), + 0x13 => command(opcode, GENERIC_READ_MEMORY, 1, 0, 0, 4, 1), + 0x0b => command(opcode, GENERIC_READ_MEMORY, 1, 8, 0, 3, 1), + 0x0c => command(opcode, GENERIC_READ_MEMORY, 1, 8, 0, 4, 1), + 0x3b => command(opcode, GENERIC_READ_MEMORY, 2, 8, 0, 3, 1), + 0x3c => command(opcode, GENERIC_READ_MEMORY, 2, 8, 0, 4, 1), + 0xbb => command(opcode, GENERIC_READ_MEMORY, 2, 4, 0, 3, 2), + 0xbc => command(opcode, GENERIC_READ_MEMORY, 2, 4, 0, 4, 2), + 0x6b => command(opcode, GENERIC_READ_MEMORY, 3, 8, 0, 3, 1), + 0x6c => command(opcode, GENERIC_READ_MEMORY, 3, 8, 0, 4, 1), + 0xeb => command(opcode, GENERIC_READ_MEMORY, 3, 6, 0, 3, 3), + 0xec => command(opcode, GENERIC_READ_MEMORY, 3, 6, 0, 4, 3), + 0x02 => command(opcode, GENERIC_WRITE_MEMORY, 1, 0, 1, 3, 1), + 0x12 => command(opcode, GENERIC_WRITE_MEMORY, 1, 0, 1, 4, 1), + 0x32 => command(opcode, GENERIC_WRITE_MEMORY, 3, 0, 1, 3, 1), + 0x34 => command(opcode, GENERIC_WRITE_MEMORY, 3, 0, 1, 4, 1), + 0x20 => command(opcode, GENERIC_WRITE_MEMORY, 0, 0, 1, 3, 1), + 0x21 => command(opcode, GENERIC_WRITE_MEMORY, 0, 0, 1, 4, 1), + 0xd8 => command(opcode, GENERIC_WRITE_MEMORY, 0, 0, 5, 3, 1), + 0xdc => command(opcode, GENERIC_WRITE_MEMORY, 0, 0, 5, 4, 1), + 0x06 | 0x04 | 0x50 | 0x66 | 0x99 => command(opcode, GENERIC_NONE, 0, 0, 0, 0, 0), + 0x05 | 0x35 | 0x15 | 0x70 | 0x9f => command(opcode, GENERIC_READ, 1, 0, 0, 0, 0), + 0x01 | 0x31 => command(opcode, GENERIC_WRITE, 1, 0, 0, 0, 0), + 0x5a => command(opcode, GENERIC_READ, 1, 8, 0, 3, 1), + 0xb7 | 0xe9 => command(opcode, RESERVED_NONE, 0, 0, 0, 0, 0), + 0xc5 => command(opcode, RESERVED_WRITE, 1, 0, 0, 0, 0), + 0xc2 => command(opcode, GENERIC_WRITE, 1, 0, 0, 0, 0), _ => return None, }; Some(entry)
diff --git a/target/ast10x0/peripherals/spimonitor/controller.rs b/target/ast10x0/peripherals/spimonitor/controller.rs index e38a4c7..252f8f3 100644 --- a/target/ast10x0/peripherals/spimonitor/controller.rs +++ b/target/ast10x0/peripherals/spimonitor/controller.rs
@@ -656,14 +656,18 @@ } } else { block += 1; - let value = regs.read_addr_filter_slot(word_index); + let value = regs + .read_addr_filter_slot_checked(word_index) + .ok_or(SpiMonitorError::InvalidAddress)?; match op { PrivilegeOp::Enable => value | (1 << bit_index), PrivilegeOp::Disable => value & !(1 << bit_index), } }; - regs.write_addr_filter_slot(word_index, updated); - if regs.read_addr_filter_slot(word_index) != updated { + if !regs.write_addr_filter_slot_checked(word_index, updated) { + return Err(SpiMonitorError::InvalidAddress); + } + if regs.read_addr_filter_slot_checked(word_index) != Some(updated) { return Err(SpiMonitorError::VerificationFailed); } }
diff --git a/target/ast10x0/peripherals/spimonitor/registers.rs b/target/ast10x0/peripherals/spimonitor/registers.rs index a44e308..01fd615 100644 --- a/target/ast10x0/peripherals/spimonitor/registers.rs +++ b/target/ast10x0/peripherals/spimonitor/registers.rs
@@ -160,6 +160,14 @@ .write(|w| unsafe { w.bits(value) }); } + /// Read an allow-command slot without panicking for an invalid index. + pub fn read_allow_cmd_slot_checked(&self, index: usize) -> Option<u32> { + self.regs() + .spipfwt_iter() + .nth(index) + .map(|register| register.read().bits()) + } + /// SPIPFWA[n]: Address filter table entry. pub fn read_addr_filter_slot(&self, index: usize) -> u32 { self.regs().spipfwa(index).read().bits() @@ -171,6 +179,24 @@ .write(|w| unsafe { w.bits(value) }); } + /// Read an address-filter slot without panicking for an invalid index. + pub fn read_addr_filter_slot_checked(&self, index: usize) -> Option<u32> { + self.regs() + .spipfwa_iter() + .nth(index) + .map(|register| register.read().bits()) + } + + /// Write an address-filter slot, returning false for an invalid index. + #[must_use] + pub fn write_addr_filter_slot_checked(&self, index: usize, value: u32) -> bool { + let Some(register) = self.regs().spipfwa_iter().nth(index) else { + return false; + }; + register.write(|w| unsafe { w.bits(value) }); + true + } + // ----------------------------------------------------------------------- // Violation log registers // -----------------------------------------------------------------------
diff --git a/target/ast10x0/tests/spimonitor/BUILD.bazel b/target/ast10x0/tests/spimonitor/BUILD.bazel index 47f0d66..8618bbf 100644 --- a/target/ast10x0/tests/spimonitor/BUILD.bazel +++ b/target/ast10x0/tests/spimonitor/BUILD.bazel
@@ -27,9 +27,13 @@ ) 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(
diff --git a/target/ast10x0/tests/spimonitor/test_common.rs b/target/ast10x0/tests/spimonitor/test_common.rs index aa85051..4b57a1c 100644 --- a/target/ast10x0/tests/spimonitor/test_common.rs +++ b/target/ast10x0/tests/spimonitor/test_common.rs
@@ -255,15 +255,20 @@ pw_log::info!("START: command table add and remove"); configured.remove_command(0x05)?; let status_slot = configured.add_command(0x05, false)?; + let status_value = configured + .regs() + .read_allow_cmd_slot_checked(status_slot) + .ok_or(TestError::Check)?; test_check!( - configured.regs().read_allow_cmd_slot(status_slot) & COMMAND_VALID_MASK != 0, + status_value & COMMAND_VALID_MASK != 0, "FAIL: command add readback" ); configured.remove_command(0x05)?; - test_check!( - configured.regs().read_allow_cmd_slot(status_slot) == 0, - "FAIL: command remove did not clear slot" - ); + let status_value = configured + .regs() + .read_allow_cmd_slot_checked(status_slot) + .ok_or(TestError::Check)?; + test_check!(status_value == 0, "FAIL: command remove did not clear slot"); configured.add_command(0x05, false)?; pw_log::info!("PASS: command table add and remove"); Ok(())