1 use gdbstub::arch::Registers; 2 use gdbstub::internal::LeBytes; 3 use num_traits::PrimInt; 4 5 /// TI-MSP430 registers. 6 /// 7 /// The register width is set based on the `<U>` type. For 16-bit MSP430 CPUs 8 /// this should be `u16` and for 20-bit MSP430 CPUs (CPUX) this should be `u32`. 9 #[derive(Debug, Default, Clone, Eq, PartialEq)] 10 pub struct Msp430Regs<U> { 11 /// Program Counter (R0) 12 pub pc: U, 13 /// Stack Pointer (R1) 14 pub sp: U, 15 /// Status Register (R2) 16 pub sr: U, 17 /// General Purpose Registers (R4-R15) 18 pub r: [U; 12], 19 } 20 21 impl<U> Registers for Msp430Regs<U> 22 where 23 U: PrimInt + LeBytes + Default + core::fmt::Debug, 24 { 25 type ProgramCounter = U; 26 pc(&self) -> Self::ProgramCounter27 fn pc(&self) -> Self::ProgramCounter { 28 self.pc 29 } 30 gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>))31 fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) { 32 macro_rules! write_le_bytes { 33 ($value:expr) => { 34 let mut buf = [0; 4]; 35 // infallible (register size a maximum of 32-bits) 36 let len = $value.to_le_bytes(&mut buf).unwrap(); 37 let buf = &buf[..len]; 38 for b in buf { 39 write_byte(Some(*b)); 40 } 41 }; 42 } 43 44 write_le_bytes!(&self.pc); 45 write_le_bytes!(&self.sp); 46 write_le_bytes!(&self.sr); 47 (0..core::mem::size_of::<U>()).for_each(|_| write_byte(None)); // Constant Generator (CG/R3) 48 for reg in self.r.iter() { 49 write_le_bytes!(reg); 50 } 51 } 52 gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()>53 fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> { 54 let ptrsize = core::mem::size_of::<U>(); 55 56 // Ensure bytes contains enough data for all 16 registers 57 if bytes.len() < ptrsize * 16 { 58 return Err(()); 59 } 60 61 let mut regs = bytes 62 .chunks_exact(ptrsize) 63 .map(|c| U::from_le_bytes(c).unwrap()); 64 65 self.pc = regs.next().ok_or(())?; 66 self.sp = regs.next().ok_or(())?; 67 self.sr = regs.next().ok_or(())?; 68 69 // Constant Generator (CG/R3) should always be 0 70 if regs.next().ok_or(())? != U::zero() { 71 return Err(()); 72 } 73 74 for reg in self.r.iter_mut() { 75 *reg = regs.next().ok_or(())? 76 } 77 78 if regs.next().is_some() { 79 return Err(()); 80 } 81 82 Ok(()) 83 } 84 } 85