Skip to content

Commit

Permalink
Merge branch 'master' into api-changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Yatekii committed May 5, 2020
2 parents 0729532 + 12615f9 commit dcce413
Show file tree
Hide file tree
Showing 16 changed files with 639 additions and 139 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Fixed a bug in the gdb-server that causes it to never halt after a continue.
- Fixed an issue where the gdb-server would always use 100 % cpu time of the core it's running on.

## [0.6.2]

### Added
Expand Down
12 changes: 4 additions & 8 deletions gdb-server/src/handlers.rs
Expand Up @@ -172,18 +172,14 @@ pub(crate) fn get_memory_map() -> Option<String> {
<memory type="ram" start="0x20000000" length="0x4000"/>
<memory type="rom" start="0x00000000" length="0x40000"/>
</memory-map>"#;
Some(
std::str::from_utf8(&gdb_sanitize_file(xml.as_bytes().to_vec(), 0, 1000))
.unwrap()
.to_string(),
)
Some(String::from_utf8(gdb_sanitize_file(xml.as_bytes(), 0, 1000)).unwrap())
}

pub(crate) fn user_halt(core: &mut Core, awaits_halt: &mut bool) -> Option<String> {
let _ = core.halt();
core.wait_for_core_halted().unwrap();
*awaits_halt = false;
Some("T05hwbreak:;".into())
Some("T02".into())
}

pub(crate) fn detach(break_due: &mut bool) -> Option<String> {
Expand All @@ -197,7 +193,7 @@ pub(crate) fn reset_halt(core: &mut Core) -> Option<String> {
Some("OK".into())
}

fn gdb_sanitize_file(mut data: Vec<u8>, offset: u32, len: u32) -> Vec<u8> {
fn gdb_sanitize_file(data: &[u8], offset: u32, len: u32) -> Vec<u8> {
let offset = offset as usize;
let len = len as usize;
let mut end = offset + len;
Expand All @@ -207,7 +203,7 @@ fn gdb_sanitize_file(mut data: Vec<u8>, offset: u32, len: u32) -> Vec<u8> {
if end > data.len() {
end = data.len();
}
let mut trimmed_data: Vec<u8> = data.drain(offset..end).collect();
let mut trimmed_data = Vec::from(&data[offset..end]);
if trimmed_data.len() >= len {
// XXX should this be <= or < ?
trimmed_data.insert(0, b'm');
Expand Down
60 changes: 44 additions & 16 deletions gdb-server/src/worker.rs
@@ -1,11 +1,13 @@
use async_std::prelude::*;
use async_std::task;
use futures::channel::mpsc;
use futures::future::FutureExt;
use futures::select;
use gdb_protocol::packet::{CheckedPacket, Kind as PacketKind};
use probe_rs::Core;
use probe_rs::Session;
use std::sync::{Arc, Mutex};
use std::time::Duration;

use crate::handlers;

Expand Down Expand Up @@ -35,7 +37,7 @@ pub async fn worker(
break
}
},
_ = await_halt(&mut core, output_stream.clone(), awaits_halt).fuse() => {}
_ = await_halt(&mut core, output_stream.clone(), &mut awaits_halt).fuse() => {}
}
}
Ok(())
Expand All @@ -51,11 +53,20 @@ pub async fn handler(
let mut break_due = false;
if packet.is_valid() {
let packet_string = String::from_utf8_lossy(&packet.data).to_string();

#[allow(clippy::if_same_then_else)]
let response: Option<String> = if packet.data.starts_with(b"qSupported") {
handlers::q_supported()
} else if packet.data.starts_with(b"vMustReplyEmpty") {
handlers::reply_empty()
} else if packet.data.starts_with(b"vCont?") {
handlers::vcont_supported()
} else if packet.data.starts_with(b"vCont;c") || packet.data.starts_with(b"c") {
handlers::run(core, awaits_halt)
} else if packet.data.starts_with(b"vCont;t") {
handlers::stop(core, awaits_halt)
} else if packet.data.starts_with(b"vCont;s") || packet.data.starts_with(b"s") {
handlers::step(core, awaits_halt)
} else if packet.data.starts_with(b"qTStatus") {
handlers::reply_empty()
} else if packet.data.starts_with(b"qTfV") {
Expand All @@ -80,14 +91,18 @@ pub async fn handler(
handlers::reply_empty()
} else if packet.data.starts_with(b"qOffsets") {
handlers::reply_empty()
} else if packet.data.starts_with(b"vCont?") {
handlers::vcont_supported()
} else if packet.data.starts_with(b"vContb;c") || packet.data.starts_with(b"c") {
handlers::run(core, awaits_halt)
} else if packet.data.starts_with(b"vContb;t") {
handlers::stop(core, awaits_halt)
} else if packet.data.starts_with(b"vContb;s") || packet.data.starts_with(b"s") {
handlers::step(core, awaits_halt)
} else if packet.data == b"QStartNoAckMode" {
// TODO: Implement No ACK mode
handlers::reply_empty()
} else if packet.data == b"QThreadSuffixSupported" {
handlers::reply_empty()
} else if packet.data == b"QListThreadsInStopReply" {
handlers::reply_empty()
} else if packet.data.starts_with(b"x") {
// TODO: Implement binary memory read
handlers::reply_empty()
} else if packet.data.starts_with(b"jThread") {
handlers::reply_empty()
} else if packet.data.starts_with(b"Z0") {
handlers::reply_empty()
} else if packet.data.starts_with(b"Z1") {
Expand All @@ -96,7 +111,7 @@ pub async fn handler(
handlers::remove_hardware_break(packet_string, core)
} else if packet.data.starts_with(b"X") {
handlers::write_memory(packet_string, &packet.data, core)
} else if packet.data.starts_with(b"qXfer:memory-mapb:read") {
} else if packet.data.starts_with(b"qXfer:memory-map:read") {
handlers::get_memory_map()
} else if packet.data.starts_with(&[0x03]) {
handlers::user_halt(core, awaits_halt)
Expand All @@ -106,18 +121,29 @@ pub async fn handler(
handlers::reset_halt(core)
} else if packet.data.starts_with(b"qTfV") {
handlers::reply_empty()
} else if packet.data.starts_with(b"qTfV") {
handlers::reply_empty()
} else {
Some("OK".into())
log::warn!(
"Unknown command: '{}'",
String::from_utf8_lossy(&packet.data)
);

if packet.data.starts_with(b"q") || packet.data.starts_with(b"v") {
// respond with an empty response to indicate that we don't suport the command
handlers::reply_empty()
} else {
Some("OK".into())
}
};

if let Some(response) = response {
let response = CheckedPacket::from_data(PacketKind::Packet, response.into_bytes());

let mut bytes = Vec::new();
response.encode(&mut bytes).unwrap();
log::debug!("{:x?}", std::str::from_utf8(&response.data).unwrap());
log::debug!(
"Response: '{:x?}'",
std::str::from_utf8(&response.data).unwrap()
);
log::debug!("-----------------------------------------------");
output_stream.unbounded_send(response)?;
};
Expand All @@ -128,14 +154,16 @@ pub async fn handler(
pub async fn await_halt(
core: &mut Core<'_>,
output_stream: Sender<CheckedPacket>,
await_halt: bool,
await_halt: &mut bool,
) {
if await_halt && core.core_halted().unwrap() {
task::sleep(Duration::from_millis(10)).await;
if *await_halt && core.core_halted().unwrap() {
let response =
CheckedPacket::from_data(PacketKind::Packet, "T05hwbreak:;".to_string().into_bytes());

let mut bytes = Vec::new();
response.encode(&mut bytes).unwrap();
*await_halt = false;

let _ = output_stream.unbounded_send(response);
}
Expand Down
1 change: 0 additions & 1 deletion probe-rs-t2rust/src/bin.rs
@@ -1,4 +1,3 @@
use probe_rs_t2rust;
use std::env;
fn main() {
let args: Vec<String> = env::args().collect();
Expand Down
11 changes: 10 additions & 1 deletion probe-rs/examples/ram_download.rs
Expand Up @@ -15,6 +15,8 @@ struct CLI {
address: u32,
#[structopt(long = "size")]
size: usize,
#[structopt(long = "protocol")]
protocol: Option<String>,
}

fn parse_hex(src: &str) -> Result<u32, ParseIntError> {
Expand All @@ -33,8 +35,13 @@ fn main() -> Result<(), &'static str> {
None => TargetSelector::Auto,
};

let protocol = match matches.protocol {
Some(protocol) => protocol.parse().map_err(|_| "Unknown protocol")?,
None => WireProtocol::Swd,
};

probe
.select_protocol(WireProtocol::Swd)
.select_protocol(protocol)
.map_err(|_| "Failed to select SWD as the transport protocol")?;
let mut session = probe
.attach(target_selector)
Expand All @@ -51,6 +58,8 @@ fn main() -> Result<(), &'static str> {

rng.fill(&mut sample_data[..]);

core.halt().unwrap();

let write_start = Instant::now();
core.write_32(matches.address, &sample_data).unwrap();

Expand Down
27 changes: 27 additions & 0 deletions probe-rs/src/architecture/riscv/assembly.rs
@@ -0,0 +1,27 @@
/// RISCV breakpoint instruction
pub const EBREAK: u32 = 0b000000000001_00000_000_00000_1110011;

/// Assemble a `lw` instruction.
pub const fn lw(offset: u32, base: u32, width: u32, destination: u32) -> u32 {
let opcode = 0b000_0011;

offset << 20 | base << 15 | width << 12 | destination << 7 | opcode
}

/// Assemble a `sw` instruction.
pub const fn sw(offset: u32, base: u32, width: u32, source: u32) -> u32 {
let opcode = 0b010_0011;

let offset_lower = offset & 0b11111;
let offset_upper = offset >> 5;

offset_upper << 25 | source << 20 | base << 15 | width << 12 | offset_lower << 7 | opcode
}

/// Assemble a `addi` instruction.
pub const fn addi(source: u32, destination: u32, immediate: u32) -> u32 {
let opcode = 0b001_0011;
let function = 0b000;

immediate << 20 | source << 15 | function << 12 | destination << 7 | opcode
}

0 comments on commit dcce413

Please sign in to comment.