From b0ecc260021fb2d1e848f46baaf2c488f799de4f Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Thu, 11 May 2023 15:13:03 +0800 Subject: [PATCH] kernel: gdb: batch 2- and 4-byte accesses Instead of always doing bytewise accesses, support 2- and 4-byte access. Additionally, recognize when multiple 4-byte reads are required. Note that an additional optimization may be made here in the future to prevent having to check every address, but this is left for a future optimization. Signed-off-by: Sean Cross --- kernel/src/debug/gdb/multi_thread_base.rs | 54 ++++++++++++++++++----- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/kernel/src/debug/gdb/multi_thread_base.rs b/kernel/src/debug/gdb/multi_thread_base.rs index 7d1226c23..6a9bbb844 100644 --- a/kernel/src/debug/gdb/multi_thread_base.rs +++ b/kernel/src/debug/gdb/multi_thread_base.rs @@ -5,6 +5,7 @@ use gdbstub::target::ext::base::single_register_access::SingleRegisterAccessOps; use gdbstub::target::TargetResult; use super::XousTarget; +use core::convert::TryInto; impl MultiThreadBase for XousTarget { fn read_registers( @@ -107,10 +108,33 @@ impl MultiThreadBase for XousTarget { .unwrap() .activate() .unwrap(); - for (offset, b) in data.iter_mut().enumerate() { - *b = crate::arch::mem::peek_memory((current_addr + offset) as *mut u8) - .unwrap_or(0xff); - // println!("<< Peek {:02x} @ {:08x}", *b, current_addr); + + if data.len() == 2 && (start_addr & 1) == 0 { + let val = crate::arch::mem::peek_memory(start_addr as *mut u16).unwrap_or(0); + for (dest, src) in data.iter_mut().zip(val.to_le_bytes()) { + *dest = src; + } + } else if data.len() == 4 && (start_addr & 3) == 0 { + let val = crate::arch::mem::peek_memory(start_addr as *mut u32).unwrap_or(0); + for (dest, src) in data.iter_mut().zip(val.to_le_bytes()) { + *dest = src; + } + } else if (data.len() & 3) == 0 && (start_addr & 3) == 0 { + let mut current_addr = current_addr; + for word in data.chunks_mut(4) { + let bytes = crate::arch::mem::peek_memory(current_addr as *mut u32) + .unwrap_or(0) + .to_le_bytes(); + for (dest, src) in word.iter_mut().zip(bytes) { + *dest = src; + } + current_addr += 4; + } + } else { + for (offset, b) in data.iter_mut().enumerate() { + *b = crate::arch::mem::peek_memory((current_addr + offset) as *mut u8) + .unwrap_or(0xff); + } } // Restore the previous PID @@ -145,13 +169,21 @@ impl MultiThreadBase for XousTarget { .unwrap() .activate() .unwrap(); - data.iter().for_each(|b| { - if let Err(_e) = crate::arch::mem::poke_memory(current_addr as *mut u8, *b) { - // panic!("couldn't poke memory: {:?}", _e); - } - // println!("Poked {:02x} @ {:08x}", *b, current_addr); - current_addr += 1; - }); + + if data.len() == 2 && (start_addr & 1) == 0 { + let val = u16::from_le_bytes(data.try_into().unwrap()); + crate::arch::mem::poke_memory(start_addr as *mut u16, val).ok(); + } else if data.len() == 4 && (start_addr & 3) == 0 { + let val = u32::from_le_bytes(data.try_into().unwrap()); + crate::arch::mem::poke_memory(start_addr as *mut u32, val).ok(); + } else { + data.iter().for_each(|b| { + if let Err(_e) = crate::arch::mem::poke_memory(current_addr as *mut u8, *b) { + // panic!("couldn't poke memory: {:?}", _e); + } + current_addr += 1; + }); + } // Restore the previous PID system_services