Compare commits
No commits in common. "9f7895a457d1710d32664a2b76f5c4b3e2b5a3e1" and "0fff4d427f7551bf14dafe948b552a94b385495a" have entirely different histories.
9f7895a457
...
0fff4d427f
3
build.rs
3
build.rs
|
@ -23,9 +23,6 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
.define("VB_LITTLE_ENDIAN", None)
|
.define("VB_LITTLE_ENDIAN", None)
|
||||||
.define("VB_SIGNED_PROPAGATE", None)
|
.define("VB_SIGNED_PROPAGATE", None)
|
||||||
.define("VB_DIV_GENERIC", None)
|
.define("VB_DIV_GENERIC", None)
|
||||||
.define("VB_DIRECT_EXECUTE", "on_execute")
|
|
||||||
.define("VB_DIRECT_READ", "on_read")
|
|
||||||
.define("VB_DIRECT_WRITE", "on_write")
|
|
||||||
.file(Path::new("shrooms-vb-core/core/vb.c"))
|
.file(Path::new("shrooms-vb-core/core/vb.c"))
|
||||||
.compile("vb");
|
.compile("vb");
|
||||||
|
|
||||||
|
|
|
@ -550,13 +550,6 @@ impl Emulator {
|
||||||
sim.read_memory(start, length, &mut buffer);
|
sim.read_memory(start, length, &mut buffer);
|
||||||
let _ = done.send(buffer);
|
let _ = done.send(buffer);
|
||||||
}
|
}
|
||||||
EmulatorCommand::WriteMemory(sim_id, start, buffer, done) => {
|
|
||||||
let Some(sim) = self.sims.get_mut(sim_id.to_index()) else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
sim.write_memory(start, &buffer);
|
|
||||||
let _ = done.send(buffer);
|
|
||||||
}
|
|
||||||
EmulatorCommand::AddBreakpoint(sim_id, address) => {
|
EmulatorCommand::AddBreakpoint(sim_id, address) => {
|
||||||
let Some(sim) = self.sims.get_mut(sim_id.to_index()) else {
|
let Some(sim) = self.sims.get_mut(sim_id.to_index()) else {
|
||||||
return;
|
return;
|
||||||
|
@ -646,7 +639,6 @@ pub enum EmulatorCommand {
|
||||||
ReadRegister(SimId, VBRegister, oneshot::Sender<u32>),
|
ReadRegister(SimId, VBRegister, oneshot::Sender<u32>),
|
||||||
WriteRegister(SimId, VBRegister, u32),
|
WriteRegister(SimId, VBRegister, u32),
|
||||||
ReadMemory(SimId, u32, usize, Vec<u8>, oneshot::Sender<Vec<u8>>),
|
ReadMemory(SimId, u32, usize, Vec<u8>, oneshot::Sender<Vec<u8>>),
|
||||||
WriteMemory(SimId, u32, Vec<u8>, oneshot::Sender<Vec<u8>>),
|
|
||||||
AddBreakpoint(SimId, u32),
|
AddBreakpoint(SimId, u32),
|
||||||
RemoveBreakpoint(SimId, u32),
|
RemoveBreakpoint(SimId, u32),
|
||||||
AddWatchpoint(SimId, u32, usize, VBWatchpointType),
|
AddWatchpoint(SimId, u32, usize, VBWatchpointType),
|
||||||
|
|
|
@ -166,8 +166,6 @@ extern "C" {
|
||||||
fn vb_set_write_callback(sim: *mut VB, callback: Option<OnWrite>) -> Option<OnWrite>;
|
fn vb_set_write_callback(sim: *mut VB, callback: Option<OnWrite>) -> Option<OnWrite>;
|
||||||
#[link_name = "vbSizeOf"]
|
#[link_name = "vbSizeOf"]
|
||||||
fn vb_size_of() -> usize;
|
fn vb_size_of() -> usize;
|
||||||
#[link_name = "vbWrite"]
|
|
||||||
fn vb_write(sim: *mut VB, address: u32, _type: VBDataType, value: i32) -> i32;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn on_frame(sim: *mut VB) -> c_int {
|
extern "C" fn on_frame(sim: *mut VB) -> c_int {
|
||||||
|
@ -178,7 +176,6 @@ extern "C" fn on_frame(sim: *mut VB) -> c_int {
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn on_execute(sim: *mut VB, address: u32, _code: *const u16, _length: c_int) -> c_int {
|
extern "C" fn on_execute(sim: *mut VB, address: u32, _code: *const u16, _length: c_int) -> c_int {
|
||||||
// SAFETY: the *mut VB owns its userdata.
|
// SAFETY: the *mut VB owns its userdata.
|
||||||
// There is no way for the userdata to be null or otherwise invalid.
|
// There is no way for the userdata to be null or otherwise invalid.
|
||||||
|
@ -202,7 +199,6 @@ extern "C" fn on_execute(sim: *mut VB, address: u32, _code: *const u16, _length:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn on_read(
|
extern "C" fn on_read(
|
||||||
sim: *mut VB,
|
sim: *mut VB,
|
||||||
address: u32,
|
address: u32,
|
||||||
|
@ -228,7 +224,6 @@ extern "C" fn on_read(
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn on_write(
|
extern "C" fn on_write(
|
||||||
sim: *mut VB,
|
sim: *mut VB,
|
||||||
address: u32,
|
address: u32,
|
||||||
|
@ -481,14 +476,6 @@ impl Sim {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_memory(&mut self, start: u32, buffer: &[u8]) {
|
|
||||||
let mut address = start;
|
|
||||||
for byte in buffer {
|
|
||||||
unsafe { vb_write(self.sim, address, VBDataType::U8, *byte as i32) };
|
|
||||||
address = address.wrapping_add(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_breakpoint(&mut self, address: u32) {
|
pub fn add_breakpoint(&mut self, address: u32) {
|
||||||
let data = self.get_state();
|
let data = self.get_state();
|
||||||
if let Err(index) = data.breakpoints.binary_search(&address) {
|
if let Err(index) = data.breakpoints.binary_search(&address) {
|
||||||
|
|
|
@ -346,9 +346,22 @@ impl GdbConnection {
|
||||||
}
|
}
|
||||||
} else if let Some(op) = req.match_some_str(["m", "x"]) {
|
} else if let Some(op) = req.match_some_str(["m", "x"]) {
|
||||||
let mut read_memory = || {
|
let mut read_memory = || {
|
||||||
let (start, length) = parse_memory_range(&mut req)?;
|
let start = req.match_hex::<u64>()?;
|
||||||
|
if !req.match_str(",") {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
let length = req.match_hex::<usize>()?;
|
||||||
|
|
||||||
let mut buf = self.memory_buf.take().unwrap_or_default();
|
let mut buf = self.memory_buf.take().unwrap_or_default();
|
||||||
buf.clear();
|
buf.clear();
|
||||||
|
|
||||||
|
// The v810 has a 32-bit address space.
|
||||||
|
// Addresses wrap within that space, but we don't need to implement that for 64-bit addresses.
|
||||||
|
// Just refuse to return any info for addresses above 0xffffffff.
|
||||||
|
let Ok(start) = u32::try_from(start) else {
|
||||||
|
return Some(buf);
|
||||||
|
};
|
||||||
|
let length = length.min((u32::MAX - start) as usize + 1);
|
||||||
if length == 0 {
|
if length == 0 {
|
||||||
return Some(buf);
|
return Some(buf);
|
||||||
}
|
}
|
||||||
|
@ -382,38 +395,6 @@ impl GdbConnection {
|
||||||
} else {
|
} else {
|
||||||
self.response()
|
self.response()
|
||||||
}
|
}
|
||||||
} else if let Some(op) = req.match_some_str(["M", "X"]) {
|
|
||||||
let mut write_memory = || {
|
|
||||||
let (start, length) = parse_memory_range(&mut req)?;
|
|
||||||
if length == 0 {
|
|
||||||
return Some(());
|
|
||||||
}
|
|
||||||
if !req.match_str(":") {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let mut buf = self.memory_buf.take().unwrap_or_default();
|
|
||||||
buf.resize(length, 0);
|
|
||||||
let successful_read = if op == "M" {
|
|
||||||
req.match_hex_bytes(&mut buf)
|
|
||||||
} else {
|
|
||||||
req.match_bytes(&mut buf)
|
|
||||||
};
|
|
||||||
if !successful_read {
|
|
||||||
self.memory_buf = Some(buf);
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let (tx, rx) = ::oneshot::channel();
|
|
||||||
self.client
|
|
||||||
.send_command(EmulatorCommand::WriteMemory(self.sim_id, start, buf, tx));
|
|
||||||
let buf = rx.recv().ok()?;
|
|
||||||
self.memory_buf = Some(buf);
|
|
||||||
Some(())
|
|
||||||
};
|
|
||||||
if write_memory().is_some() {
|
|
||||||
self.response().write_str("OK")
|
|
||||||
} else {
|
|
||||||
self.response()
|
|
||||||
}
|
|
||||||
} else if req.match_str("Z") {
|
} else if req.match_str("Z") {
|
||||||
let mut parse_request = || {
|
let mut parse_request = || {
|
||||||
let type_ = req.match_hex::<u8>()?;
|
let type_ = req.match_hex::<u8>()?;
|
||||||
|
@ -502,23 +483,6 @@ impl Drop for GdbConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse a memory range into a start and a length.
|
|
||||||
fn parse_memory_range(req: &mut Request<'_>) -> Option<(u32, usize)> {
|
|
||||||
let start = req.match_hex::<u64>()?;
|
|
||||||
if !req.match_str(",") {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
let length = req.match_hex::<usize>()?;
|
|
||||||
let Ok(start) = u32::try_from(start) else {
|
|
||||||
// The v810 has a 32-bit address space.
|
|
||||||
// Addresses wrap within that space, but we don't need to implement that for 64-bit addresses.
|
|
||||||
// Just refuse to return any info for addresses above 0xffffffff.
|
|
||||||
return Some((0, 0));
|
|
||||||
};
|
|
||||||
let length = length.min((u32::MAX - start) as usize + 1);
|
|
||||||
Some((start, length))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn debug_stop_reason_string(reason: Option<DebugStopReason>) -> String {
|
fn debug_stop_reason_string(reason: Option<DebugStopReason>) -> String {
|
||||||
let mut result = String::new();
|
let mut result = String::new();
|
||||||
result += if reason.is_some() { "T05;" } else { "T00;" };
|
result += if reason.is_some() { "T05;" } else { "T00;" };
|
||||||
|
|
|
@ -74,15 +74,6 @@ impl Request<'_> {
|
||||||
self.buffer = self.buffer.split_at(buffer.len()).1;
|
self.buffer = self.buffer.split_at(buffer.len()).1;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn match_bytes(&mut self, buffer: &mut [u8]) -> bool {
|
|
||||||
if self.buffer.len() < buffer.len() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
buffer.copy_from_slice(&self.buffer[0..buffer.len()]);
|
|
||||||
self.buffer = self.buffer.split_at(buffer.len()).1;
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RequestSource<R> {
|
pub struct RequestSource<R> {
|
||||||
|
|
Loading…
Reference in New Issue