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 <sean@xobs.io>
This commit is contained in:
Sean Cross 2023-05-11 15:13:03 +08:00
parent 55d27cbf1b
commit b0ecc26002

View file

@ -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