-
Notifications
You must be signed in to change notification settings - Fork 204
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
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this 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.
I just noticed that |
The readme can also be updated to mention this support. |
There was a problem hiding this 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?
Ah never mind, I saw your test. |
@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? |
I just merged support for first-party tests so we could add this as part of this PR now! |
Hi Jordan and Tim, sorry for the late response. I will commit the requested changes today. |
There was a problem hiding this 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.
Okayy, I will add this in the next commit. |
There was a problem hiding this 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.
There was a problem hiding this 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.
Good point. What about just modifying |
That should work, sure. |
@MuhammadHammad001 It would be good to merge this soon when the |
@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. |
Hi @jordancarlin, I will surely do it by tomorrow. |
@jordancarlin @Timmmm @pmundkur Can you please review the code at your ease :))) |
There was a problem hiding this 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!
There was a problem hiding this 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.
model/riscv_mem.sail
Outdated
@@ -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) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
model/riscv_mem.sail
Outdated
@@ -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 = { |
There was a problem hiding this comment.
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)
.
There was a problem hiding this comment.
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]>
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 |
Signed-off-by: Muhammad Hammad Bashir <[email protected]>
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.