pub struct Backdoor { /* private fields */ }Expand description
A struct which represents an active backdoor loader connection.
Implementations§
Source§impl Backdoor
impl Backdoor
Sourcepub fn new(
dmi: OpenOcdDmi,
jtag_speed_khz: u64,
enumerate: bool,
) -> Result<Self>
pub fn new( dmi: OpenOcdDmi, jtag_speed_khz: u64, enumerate: bool, ) -> Result<Self>
Construct a Backdoor from a DMI connection to the backdoor TAP. Optionally
enumerate and discover information about all available targets.
pub fn enumerate(&mut self) -> Result<()>
Sourcepub fn set_done(self) -> Result<()>
pub fn set_done(self) -> Result<()>
Communicate with the backdoor loader that we are finished using it.
This transitions the bkdr_loader from it from its “Preload” state to “Mission mode”, causing it to re-route incoming JTAG back to the regular downstream interface.
Sourcepub fn targets(&self) -> &[BackdoorTargetInfo]
pub fn targets(&self) -> &[BackdoorTargetInfo]
Retrieve information about all of the targets available via the backdoor interface.
Sourcepub fn target_by_id(&mut self, id: u32) -> Option<BackdoorTarget<'_>>
pub fn target_by_id(&mut self, id: u32) -> Option<BackdoorTarget<'_>>
Borrow a target by its integer identifier. Only one BackdoorTarget can exist at a time.
Sourcepub fn target_by_id_str(
&mut self,
id: &str,
) -> Result<Option<BackdoorTarget<'_>>>
pub fn target_by_id_str( &mut self, id: &str, ) -> Result<Option<BackdoorTarget<'_>>>
Borrow a target by its string identifier. Only one BackdoorTarget can exist at a time.
Sourcepub fn write_target(
&mut self,
target_index: u8,
start: u32,
words: &[Word],
write_all: bool,
check_status: bool,
) -> Result<()>
pub fn write_target( &mut self, target_index: u8, start: u32, words: &[Word], write_all: bool, check_status: bool, ) -> Result<()>
Write a sequence of words at a given offset (word index) to a specified target’s memory,
using the bkdr_loader’s AUTO_INCR write mode.
With AUTO_INCR set, writing the highest-indexed WRITE_DATA register needed for the
target’s line width both commits a bkdr write at the current INDEX and advances INDEX
by one, so a full sequential range can be streamed without an INDEX write per word.
That top-word write must always happen (it’s what fires the commit), but writes to any
lower-indexed WRITE_DATA registers can still be elided by the write_all parameter,
using shadow CSRs to determine when register contents have genuinely changed since the
previous word.
The check_status parameter is used to control whether the status bit is polled
after all words are written, to check for any errors; it also reads back INDEX to
verify the cursor advanced exactly once per word (i.e. no commit was lost).
Sourcepub fn write_target_word(
&mut self,
target_index: u8,
index: u32,
word: &Word,
check_status: bool,
) -> Result<()>
pub fn write_target_word( &mut self, target_index: u8, index: u32, word: &Word, check_status: bool, ) -> Result<()>
Write a single word at a given word index to a specified target’s memory, using the
bkdr_loader’s manual (non-AUTO_INCR) write mode: WRITE_DATA is loaded, then writing
INDEX itself commands the write to that exact address.
Unlike Backdoor::write_target, this does not move any auto-increment cursor and can
address any word directly, which is handy for one-off single-word pokes that don’t want
to reason about a running INDEX. The check_status parameter is used to control whether
the status bit is polled afterwards, to check for any errors.
Sourcepub fn read_target(
&mut self,
target_index: u8,
start: u32,
count: u32,
check_status: bool,
) -> Result<Vec<Word>>
pub fn read_target( &mut self, target_index: u8, start: u32, count: u32, check_status: bool, ) -> Result<Vec<Word>>
Read a sequence of words at a given offset (word index) from a specified target’s memory,
using the bkdr_loader’s AUTO_INCR read mode.
With AUTO_INCR set and WRITE_ENA clear, reading the highest-indexed READ_DATA
register needed for the target’s line width advances INDEX by one (no bkdr write is
ever triggered on the read side), so a full sequential range can be streamed with a single
INDEX write up front rather than one per word. Because that top-word read is what
advances INDEX, each line’s registers must be read in ascending order (topmost last),
reading it out of order would advance past data that hasn’t been collected yet.
The check_status parameter is used to control whether the status bit is polled
after all words are read, to check for any errors; it also reads back INDEX to
verify the cursor advanced exactly once per word.
Sourcepub fn read_target_word(
&mut self,
target_index: u8,
index: u32,
check_status: bool,
) -> Result<Word>
pub fn read_target_word( &mut self, target_index: u8, index: u32, check_status: bool, ) -> Result<Word>
Read a single word at a given word index from a specified target’s memory, using the
bkdr_loader’s manual (non-AUTO_INCR) read mode: writing INDEX addresses the word, then
READ_DATA is read back.
Unlike Backdoor::read_target, this does not move any auto-increment cursor and can
address any word directly, which is handy for one-off single-word peeks. The
check_status parameter is used to control whether the status bit is polled afterwards,
to check for any errors.
Sourcepub fn clear_target(
&mut self,
target_index: u8,
word: &Word,
check_status: bool,
) -> Result<()>
pub fn clear_target( &mut self, target_index: u8, word: &Word, check_status: bool, ) -> Result<()>
Clear the entire memory of a specified target with a given word.
An optimized fast-path for clearing memories, primarily used to replicate existing
bitstream synthesis defaults. The check_status parameter is used to control
whether the status bit is polled after clearing, to check for any errors.
Sourcepub fn read_target_hash(&mut self, target_index: u8) -> Result<u32>
pub fn read_target_hash(&mut self, target_index: u8) -> Result<u32>
Read a specified target’s HASH_LAST_LOADED register.
This is a plain rw register with no side effects of its own: hardware only stores
whatever value software last wrote to it, and never clears it on the button/rst_ni
reset used to re-enter the backdoor loader. It exists so a caller can stash a hash
of a target’s memory content across preloads, and skip re-writing that content if
the hash of what it’s about to write hasn’t changed.
Sourcepub fn write_target_hash(&mut self, target_index: u8, hash: u32) -> Result<()>
pub fn write_target_hash(&mut self, target_index: u8, hash: u32) -> Result<()>
Write a specified target’s HASH_LAST_LOADED register. See Backdoor::read_target_hash.
Sourcepub fn read_usr_access_timestamp(&mut self) -> Result<u32>
pub fn read_usr_access_timestamp(&mut self) -> Result<u32>
Read the FPGA’s USR_ACCESS_TIMESTAMP register: the same value embedded in the
bitstream’s USR_ACCESS primitive at build time (see util::usr_access::usr_access_get).
Unlike that value, this one is read directly from the FPGA fabric’s configuration over
the backdoor TAP, so it identifies the bitstream currently loaded.