Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support RTT for 64-bit processors #2296

Merged
merged 23 commits into from
May 16, 2024

Conversation

tnishinaga
Copy link
Contributor

I added support RTT for 64-bit processors.

The 64-bit mode is not yet supported(TBD) by SEGGER RTT.
https://github.com/SEGGERMicro/RTT/blob/master/RTT/SEGGER_RTT.h#L216-L217

But I created a code that works with the defmt_rtt.
https://github.com/knurling-rs/defmt/blob/main/firmware/defmt-rtt/src/lib.rs#L124-L136

I checked it works on Raspberry Pi 4(64bit) and Raspberry Pi Pico(32bit).

@tnishinaga tnishinaga changed the title Add support RTT for 64bit processors Add support RTT for 64-bit processors Mar 17, 2024
Copy link
Member

@Yatekii Yatekii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for implementing this!

Is there a reason we want to allow more channels in 64bit archs?

@tnishinaga
Copy link
Contributor Author

Is there a reason we want to allow more channels in 64bit archs?

I thought I didn't change the number of max channels.
Could you tell me which part you are pointing out?

// Memory contents read in advance, starting from ptr
mem_in: Option<&[u8]>,
) -> Result<Option<Rtt>, Error> {
let is_64bit = match core.instruction_set()? {
Copy link
Contributor

@bugadani bugadani Mar 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be a lot nicer as if matches!(core.instruction_set()?, probe_rs_target::InstructionSet::A64). We only need to list the ones that are 64-bit. I realize the downside is that adding new architectures are immediately treated as 32-bit, though, so maybe instead this logic could be moved into a function like InstructionSet::width()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so maybe instead this logic could be moved into a function like InstructionSet::width()?

In this code, I want to know the size of the target integer(32bit or 64bit).
I'm checking it from the InstructioSet now, but I think there has to be a better than the current method.
Could you please tell me if you know of any good ideas?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found that Armv8a state has an is_64_bit flag, so I changed this code to use it.
008aa3a

core.read(ptr.into(), &mut mem)?;
let mut mem = vec![
0u8;
if is_64bit {
Copy link
Contributor

@bugadani bugadani Mar 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you instead store the width-dependent constants in fields first, to avoid a bunch of (mostly) unnecessary if-else?

In other places, you could probably abstract away the if 64-bit { do64 } else { do32 } code into helper functions just to clean the implementation up a bit. I'm not sure what would be the nicest, but I'm sure we can do better than an if-else everywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sure we can do better than an if-else everywhere.

I agree.
I am refactoring RTT codes, but it will take time to complete.

tnishinaga@72758b0

So, I would be happy if you could merge the current code first.

Copy link
Contributor Author

@tnishinaga tnishinaga Apr 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for waiting.
The refactor is complete now 04f918e.
Could you please review it again?

probe-rs/src/rtt/channel.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@bugadani bugadani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks better, thank you for working on this. I have a few observations that I think could improve this PR slightly, please take a look.

@@ -260,7 +411,7 @@ impl Rtt {
.into_iter()
.filter_map(|range| {
let range_len = match range.end.checked_sub(range.start) {
Some(v) if v < Self::MIN_SIZE as u64 => return None,
Some(v) if v < (if is_64_bit {std::mem::size_of::<RttControlBlockHeaderInner<u64>>()} else {std::mem::size_of::<RttControlBlockHeaderInner<u32>>()} as u64) => return None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't the most elegant way,

  • Complex guard conditions like this are hard to understand.
  • This is the third place where you implement the bool -> pointer width conversion. You should probably add a RttControlBlockHeader(Inner?)::size(is_64_bit: bool) function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your review!
I fixed it 22e9c7c

@@ -250,8 +401,8 @@ impl Rtt {
tracing::debug!("Scanning region: {:?}", region);

vec![Range {
start: region.start as u64,
end: region.end as u64,
start: region.start,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be a region.clone()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!
e8741b5

}

pub fn flags_offset(&self) -> usize {
std::mem::size_of::<Self>() - std::mem::size_of::<T>()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use offset_of! here? Also, considering these functions are (almost?) always used to calculate some memory access offset, I think it would be better if all three of these returned u64

}

pub fn read_buffer_ptr_offset(&self) -> usize {
std::mem::size_of::<RttChannelBufferInnerHeader<T>>() + std::mem::size_of::<T>()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty hard to understand because the second size_of points in the middle of an inner struct. Although offset_of_nested is not stable yet in Rust, this might still be a similarly good place to use offset_of!, like std::mem::offset_of!(Self, buffer_offset) + std::mem::offset_of!(RttChannelBufferInnerBufferOffset<T>, read_offset)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for sharing your good method!

I rewrote *_offset functions using offset_of!.
0473385

@Tiwalun
Copy link
Member

Tiwalun commented Apr 8, 2024

The 64-bit mode is not yet supported(TBD) by SEGGER RTT.
https://github.com/SEGGERMicro/RTT/blob/master/RTT/SEGGER_RTT.h#L216-L217

Just so you're aware, that repository seems to be outdated. The latest code which you can download from the Segger website does seem to support 64-bit mode.

@tnishinaga
Copy link
Contributor Author

Just so you're aware, that repository seems to be outdated. The latest code which you can download from the Segger website does seem to support 64-bit mode.

Thank you for letting me know 😄

I downloaded the latest codes(SEGGER_RTT_V796c.tgz) from https://www.segger.com/downloads/jlink#J-LinkSoftwareAndDocumentationPack and I checked these codes.
However, I could not find any code that supports ARMv8a.

Could you please tell me where is the codes to support 64-bit mode?

@Tiwalun
Copy link
Member

Tiwalun commented Apr 10, 2024

Could you please tell me where is the codes to support 64-bit mode?

You might be right, I saw that they support Cortex-A and assumed that meant 64 bit. But it seems they only support ARMv7-A, which is 32-bit.

Of course, the Segger C code just uses unsigned, so I guess it changes layout automatically...

@bugadani bugadani requested a review from Yatekii May 11, 2024 14:02
@bugadani bugadani added this pull request to the merge queue May 16, 2024
@bugadani
Copy link
Contributor

Thank you very much :)

Merged via the queue into probe-rs:master with commit bdf2f46 May 16, 2024
19 checks passed
@tnishinaga tnishinaga deleted the support_64bit_rtt branch May 17, 2024 02:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants