Skip to content

Big endianness Support added #751

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

Open
wants to merge 20 commits into
base: master
Choose a base branch
from

Conversation

MuhammadHammad001
Copy link
Contributor

@MuhammadHammad001 MuhammadHammad001 commented Feb 19, 2025

Hi @jordancarlin and @Timmmm
This PR adds the support for the big endianness in Sail RISC-V.

The test for the verification of this support is also added in this PR.

Copy link
Collaborator

@jordancarlin jordancarlin left a comment

Choose a reason for hiding this comment

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

Thanks for working on this! I left some initial comments below.

One other thing that I don't see here is the necessary modification to the reset function. Reset should set endianness back to little-endian if supported.

Copy link

github-actions bot commented Feb 19, 2025

Test Results

400 tests  +2   400 ✅ +2   1m 45s ⏱️ -1s
  1 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 1ecd7c7. ± Comparison against base commit 3dd1e59.

♻️ This comment has been updated with latest results.

@nadime15
Copy link
Contributor

nadime15 commented Feb 19, 2025

I just noticed that sstatus also has a UBE bit. It should be added to bitfield Sstatus including lower_mstatus() and lift_sstatus()

@jordancarlin jordancarlin linked an issue Feb 20, 2025 that may be closed by this pull request
@pmundkur
Copy link
Collaborator

The readme can also be updated to mention this support.

Copy link
Collaborator

@Timmmm Timmmm left a comment

Choose a reason for hiding this comment

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

Looking pretty close to me. I think we will need some kind of testing for this... It feels like the sort of thing that is easy to screw up without knowing. How do you compile a big endian ELF though?

@Timmmm
Copy link
Collaborator

Timmmm commented Feb 26, 2025

Ah never mind, I saw your test.

@nadime15 nadime15 mentioned this pull request Feb 26, 2025
2 tasks
@jordancarlin
Copy link
Collaborator

@MuhammadHammad001 Seems like this is pretty close. Would be good to get merged before conflicts start to build. Any chance you can finish it off soon?

@Timmmm
Copy link
Collaborator

Timmmm commented Mar 7, 2025

The test for the verification of this support is available here.

I just merged support for first-party tests so we could add this as part of this PR now!

@MuhammadHammad001
Copy link
Contributor Author

@MuhammadHammad001 Seems like this is pretty close. Would be good to get merged before conflicts start to build. Any chance you can finish it off soon?

Hi Jordan and Tim, sorry for the late response. I will commit the requested changes today.

Copy link
Collaborator

@jordancarlin jordancarlin left a comment

Choose a reason for hiding this comment

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

Looks very close at this point! One more small comment.

@MuhammadHammad001
Copy link
Contributor Author

The test for the verification of this support is available here.

I just merged support for first-party tests so we could add this as part of this PR now!

Okayy, I will add this in the next commit.

Copy link
Collaborator

@jordancarlin jordancarlin left a comment

Choose a reason for hiding this comment

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

LGTM once the test is added. Down the road we should add a configuration option to enable or disable big endianness support. Feel free to add a TODO comment in the code where the value of MBE is set to remind us of this.

@jordancarlin jordancarlin requested a review from Timmmm March 13, 2025 17:56
Copy link
Collaborator

@pmundkur pmundkur left a comment

Choose a reason for hiding this comment

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

mmio_read() and mmio_write() also need to be modified for endianness control.

@jordancarlin
Copy link
Collaborator

mmio_read() and mmio_write() also need to be modified for endianness control.

Good point. What about just modifying checked_mem_write and checked_mem_read so it doesn’t need to be implemented in two different places?

@pmundkur
Copy link
Collaborator

mmio_read() and mmio_write() also need to be modified for endianness control.

Good point. What about just modifying checked_mem_write and checked_mem_read so it doesn’t need to be implemented in two different places?

That should work, sure.

@pmundkur
Copy link
Collaborator

@MuhammadHammad001 It would be good to merge this soon when the mmio issue is fixed and the test is added.

@jordancarlin
Copy link
Collaborator

@MuhammadHammad001 is this something you'll be able to finish up soon? If not, I might finish it up myself in about a week if that's ok with you.

@MuhammadHammad001
Copy link
Contributor Author

Hi @jordancarlin, I will surely do it by tomorrow.

@MuhammadHammad001
Copy link
Contributor Author

@jordancarlin @Timmmm @pmundkur
Hi, I just added the test as well and also the support for big endianness.

Can you please review the code at your ease :)))

Copy link
Collaborator

@Timmmm Timmmm left a comment

Choose a reason for hiding this comment

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

Some minor things but it looks pretty close.

Haven't read the test but it sounds like it found some issues so good work there!

Copy link
Collaborator

@pmundkur pmundkur left a comment

Choose a reason for hiding this comment

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

Thanks for adding the test; haven't checked it yet.

@@ -102,10 +112,10 @@ function checked_mem_read forall 'n, 0 < 'n <= max_mem_access . (
Some(e) => Err(e),
None() => {
if within_mmio_readable(paddr, width)
then MemoryOpResult_add_meta(mmio_read(t, paddr, width), default_meta)
then MemoryOpResult_add_meta(mmio_read(t, paddr, width, is_big_endian(t) & not(t == Execute())), default_meta)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Wouldn't it have been easier to just handle endianness in checked_mem_read/write as suggested here:
#751 (comment)

That way I think you wouldn't have needed to touch riscv_platform.sail

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For write, yes, I have updated it. But, for read, I don't know how we can handle it here as we print the data in the phys_mem_read functions, so we can get the data from those functions and reverse them here but in the log we will have a different value....

Or am I mis-understanding this?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it's better just to always print them little endian in the log. The code will be a lot simpler, it's debatable which way it should be printed, and I think virtually nobody will be using big endian anyway so it probably doesn't matter too much.

@@ -63,8 +63,16 @@ function write_kind_of_flags (aq : bool, rl : bool, con : bool) -> write_kind =
(true, false, true) => throw(Error_not_implemented("sc.aq"))
}

function is_big_endian(typ : AccessType(ext_access_type)) -> bool = {
Copy link
Collaborator

@jordancarlin jordancarlin Apr 9, 2025

Choose a reason for hiding this comment

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

Why not have this be something like get_endianness that returns a type from the Endianness enum and push the check for an Execute access into it? So it becomes something like:

function get_endianness(typ : AccessType(ext_access_type)) -> Endianness = {
     match (typ, effectivePrivilege(typ, mstatus, cur_privilege)) {
       (Execute(), _)   => LittleEndian
       (_, Machine)     => if bits_to_bool(mstatus[MBE]) then BigEndian else LittleEndian,
       (_, Supervisor)  => if bits_to_bool(mstatus[SBE]) then BigEndian else LittleEndian,
       (_, User)        => if bits_to_bool(mstatus[UBE]) then BigEndian else LittleEndian,
     }
 }

Then you can replace all of the uses of let current_endianness: Endianness = if is_big_endian(typ) & typ != Execute() then BigEndian else LittleEndian with just get_endianness(typ).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea! I will implement this

Signed-off-by: Muhammad Hammad Bashir <[email protected]>
@Timmmm
Copy link
Collaborator

Timmmm commented Apr 9, 2025

I wonder if we should try to get #467 merged before this, since I don't think they will work together currently, and I think the endianness conversion should actually go in vmem_read/write().

@MuhammadHammad001
Copy link
Contributor Author

Hi @Timmmm Any update on merging this PR? Is there anybody working on the PR #467 ?

Signed-off-by: Muhammad Hammad Bashir <[email protected]>
@jordancarlin
Copy link
Collaborator

Any update on merging this PR? Is there anybody working on the PR #467 ?

@Alasdair and @pmundkur are working on #467 and it should hopefully be updated soon.

@pmundkur
Copy link
Collaborator

Hi @Timmmm Any update on merging this PR? Is there anybody working on the PR #467 ?

I'm working on rebasing this PR. I should have something pretty soon.

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.

Support for mstatus MBE, SBE
6 participants