peripherals/i2c: include address byte in slave_read, fix IRQ storm
diff --git a/target/ast10x0/peripherals/i2c/slave.rs b/target/ast10x0/peripherals/i2c/slave.rs
index 9888549..360e988 100644
--- a/target/ast10x0/peripherals/i2c/slave.rs
+++ b/target/ast10x0/peripherals/i2c/slave.rs
@@ -128,13 +128,13 @@
             self.regs().i2cs4c().read().dmarx_actual_len_byte().bits() as usize
         } else {
             // Hardware includes the I2C address byte in the buffer count (packet mode,
-            // I2CC00 bit 20). Subtract 1 to report only the payload byte count.
+            // I2CC00 bit 20). Report the full count including that byte, consistent
+            // with what slave_read returns.
             self.regs()
                 .i2cc0c()
                 .read()
                 .actual_rxd_pool_buffer_size()
-                .bits()
-                .saturating_sub(1) as usize
+                .bits() as usize
         }
     }
 
@@ -318,20 +318,20 @@
         // Get receive length from buffer length register
         if self.xfer_mode == I2cXferMode::BufferMode {
             // AST_I2CC_SLAVE_PKT_SAVE_ADDR (I2CC00 bit 20) deposits the I2C
-            // address byte at buffer offset 0. Read the raw count once, subtract
-            // 1 for that byte, then copy only the payload (skipping offset 0).
+            // address byte at buffer offset 0. Include it in the returned data;
+            // callers that need the full SMBus frame (e.g. MctpI2cEncap::decode)
+            // depend on it being present.
             let raw = self
                 .regs()
                 .i2cc0c()
                 .read()
                 .actual_rxd_pool_buffer_size()
                 .bits() as usize;
-            let data_len = raw.saturating_sub(1);
-            let to_read = data_len.min(buffer.len()).min(BUFFER_SIZE - 1);
+            let to_read = raw.min(buffer.len()).min(BUFFER_SIZE);
 
             let mut tmp = [0u8; BUFFER_SIZE];
-            self.copy_from_buffer(&mut tmp[..1 + to_read])?;
-            buffer[..to_read].copy_from_slice(&tmp[1..1 + to_read]);
+            self.copy_from_buffer(&mut tmp[..to_read])?;
+            buffer[..to_read].copy_from_slice(&tmp[..to_read]);
 
             // Re-enable RX buffer
             let mut cmd = constants::AST_I2CS_ACTIVE_ALL | constants::AST_I2CS_PKT_MODE_EN;
@@ -344,15 +344,13 @@
         } else if self.xfer_mode == I2cXferMode::DmaMode {
             // DMA mode: the hardware has already DMA'd into `self.dma_buf`.
             // AST_I2CC_SLAVE_PKT_SAVE_ADDR deposits the address byte at dma_buf[0];
-            // subtract 1 and skip it, matching the buffer-mode treatment above.
+            // include it in the returned data (matches buffer-mode treatment above).
             let hw_len = self.regs().i2cs4c().read().dmarx_actual_len_byte().bits() as usize;
-            let data_len = hw_len.saturating_sub(1);
-            let to_read = data_len.min(buffer.len());
+            let to_read = hw_len.min(buffer.len());
 
             if let Some(dma_buf) = self.slave_dma_buf.as_deref() {
-                let src_len = to_read.min(dma_buf.len().saturating_sub(1));
-                if let (Some(src), Some(dst)) =
-                    (dma_buf.get(1..1 + src_len), buffer.get_mut(..src_len))
+                let src_len = to_read.min(dma_buf.len());
+                if let (Some(src), Some(dst)) = (dma_buf.get(..src_len), buffer.get_mut(..src_len))
                 {
                     dst.copy_from_slice(src);
                 }
@@ -464,6 +462,14 @@
         let status = self.regs().i2cs24().read().bits();
 
         if status == 0 {
+            // Master status register i2cm14 retains bits after a master operation
+            // and keeps the shared IRQ line asserted. Clear it here to stop the storm.
+            let m14 = self.regs().i2cm14().read().bits();
+            if m14 != 0 {
+                unsafe {
+                    self.regs().i2cm14().write(|w| w.bits(m14));
+                }
+            }
             return None;
         }
 
diff --git a/target/ast10x0/tests/peripherals/i2c/i2c_irq/slave_target.rs b/target/ast10x0/tests/peripherals/i2c/i2c_irq/slave_target.rs
index ea0852c..bf3f9a7 100644
--- a/target/ast10x0/tests/peripherals/i2c/i2c_irq/slave_target.rs
+++ b/target/ast10x0/tests/peripherals/i2c/i2c_irq/slave_target.rs
@@ -27,7 +27,9 @@
 pub struct Target {}
 
 const SLAVE_ADDR: u8 = 0x42;
-const EXPECTED_WRITE: &[u8] = &[0xAA, 0xBB, 0xCC, 0xDD];
+// SLAVE_PKT_SAVE_ADDR prepends dest address byte (SLAVE_ADDR << 1) at offset 0,
+// followed by the master's payload [0xAA, 0xBB, 0xCC, 0xDD].
+const EXPECTED_WRITE: &[u8] = &[SLAVE_ADDR << 1, 0xAA, 0xBB, 0xCC, 0xDD];
 const READ_RESPONSE: &[u8] = &[0x55];
 
 fn i2c2_config() -> I2cConfig {
diff --git a/target/ast10x0/tests/peripherals/i2c/i2c_slave_rx/target.rs b/target/ast10x0/tests/peripherals/i2c/i2c_slave_rx/target.rs
index 2159999..4d2c934 100644
--- a/target/ast10x0/tests/peripherals/i2c/i2c_slave_rx/target.rs
+++ b/target/ast10x0/tests/peripherals/i2c/i2c_slave_rx/target.rs
@@ -18,8 +18,9 @@
 /// Slave address the test binary listens on.
 const SLAVE_ADDR: u8 = 0x42;
 
-/// Payload the master binary sends.
-const EXPECTED_PAYLOAD: &[u8] = &[0xDE, 0xAD, 0xBE, 0xEF];
+/// Expected buffer contents: SLAVE_PKT_SAVE_ADDR prepends dest address byte
+/// (SLAVE_ADDR << 1) at offset 0, followed by the master's payload [0xDE, 0xAD, 0xBE, 0xEF].
+const EXPECTED_PAYLOAD: &[u8] = &[SLAVE_ADDR << 1, 0xDE, 0xAD, 0xBE, 0xEF];
 
 /// Bus 2 config: standard-speed buffer-mode, no SMBus timeout.
 const SLAVE_CFG: I2cConfig = I2cConfig {
@@ -119,15 +120,17 @@
     let received = &rx[..n];
     if received != EXPECTED_PAYLOAD {
         pw_log::error!(
-            "payload mismatch: got [{:02x} {:02x} {:02x} {:02x}] expected [{:02x} {:02x} {:02x} {:02x}]",
+            "payload mismatch: got [{:02x} {:02x} {:02x} {:02x} {:02x}] expected [{:02x} {:02x} {:02x} {:02x} {:02x}]",
             received[0] as u32,
             received[1] as u32,
             received[2] as u32,
             received[3] as u32,
+            received[4] as u32,
             EXPECTED_PAYLOAD[0] as u32,
             EXPECTED_PAYLOAD[1] as u32,
             EXPECTED_PAYLOAD[2] as u32,
             EXPECTED_PAYLOAD[3] as u32,
+            EXPECTED_PAYLOAD[4] as u32,
         );
         return Err("payload content mismatch");
     }
diff --git a/target/ast10x0/tests/peripherals/i2c/i2c_slave_rx_ipc/slave_rx_main.rs b/target/ast10x0/tests/peripherals/i2c/i2c_slave_rx_ipc/slave_rx_main.rs
index fe775b7..5f48c3c 100644
--- a/target/ast10x0/tests/peripherals/i2c/i2c_slave_rx_ipc/slave_rx_main.rs
+++ b/target/ast10x0/tests/peripherals/i2c/i2c_slave_rx_ipc/slave_rx_main.rs
@@ -21,8 +21,9 @@
 /// Slave address the test listens on.
 const SLAVE_ADDR: u8 = 0x42;
 
-/// Payload the master binary sends.
-const EXPECTED_PAYLOAD: &[u8] = &[0xDE, 0xAD, 0xBE, 0xEF];
+/// Expected buffer contents: SLAVE_PKT_SAVE_ADDR prepends dest address byte
+/// (SLAVE_ADDR << 1) at offset 0, followed by the master's payload [0xDE, 0xAD, 0xBE, 0xEF].
+const EXPECTED_PAYLOAD: &[u8] = &[SLAVE_ADDR << 1, 0xDE, 0xAD, 0xBE, 0xEF];
 
 macro_rules! fail {
     ($msg:literal) => {{
@@ -80,11 +81,12 @@
 
     if &rx[..event.data_len] != EXPECTED_PAYLOAD {
         pw_log::error!(
-            "payload mismatch: got [{:02x} {:02x} {:02x} {:02x}]",
+            "payload mismatch: got [{:02x} {:02x} {:02x} {:02x} {:02x}]",
             rx[0] as u32,
             rx[1] as u32,
             rx[2] as u32,
             rx[3] as u32,
+            rx[4] as u32,
         );
         let _ = syscall::debug_shutdown(Err(pw_status::Error::DataLoss));
         loop {}